on xenial help sign in
Merged trunk, resolving conflict in tests/autopilot/unity8/shell/emulators/main_window.py.
9b06d16Allan LeSage
Bottombar/Bottombar.qml+4−4
@@ -16,10 +16,10 @@
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18import "../Components"
18import "../Components"
19−import "../Components/Math.js" as MathLocal
19+import Utils 0.1
20−import Unity 0.1
21import Unity.Application 0.1
20import Unity.Application 0.1
22import Ubuntu.Gestures 0.1
21import Ubuntu.Gestures 0.1
22+import Ubuntu.Components 0.1
23
23
24Item {
24Item {
25 id: bottombar
25 id: bottombar
@@ -82,7 +82,7 @@ Item {
82
82
83 readonly property bool centeredHud: parent.width < units.gu(68) // Nexus 7 has 67 gu width
83 readonly property bool centeredHud: parent.width < units.gu(68) // Nexus 7 has 67 gu width
84
84
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)
86 y: bottombar.height - bottomEdgeButtonCenterDistance - (height / 2) - bottomMargin
86 y: bottombar.height - bottomEdgeButtonCenterDistance - (height / 2) - bottomMargin
87 z: 1
87 z: 1
88 visible: opacity != 0
88 visible: opacity != 0
@@ -136,7 +136,7 @@ Item {
136 readonly property real distanceFromThreshold: (-distance) - distanceThreshold // distance is negative
136 readonly property real distanceFromThreshold: (-distance) - distanceThreshold // distance is negative
137 readonly property real revealDistance: units.gu(2)
137 readonly property real revealDistance: units.gu(2)
138 readonly property real commitDistance: units.gu(6)
138 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)
140
140
141 onStatusChanged: {
141 onStatusChanged: {
142 if (status === DirectionalDragArea.WaitingForTouch) {
142 if (status === DirectionalDragArea.WaitingForTouch) {
CMakeLists.txt+10−1
@@ -58,7 +58,16 @@ find_package(Qt5DBus)
58include(GNUInstallDirs)
58include(GNUInstallDirs)
59
59
60set(SHELL_APP_DIR ${CMAKE_INSTALL_DATADIR}/unity8)
60set(SHELL_APP_DIR ${CMAKE_INSTALL_DATADIR}/unity8)
61−set(SHELL_PRIVATE_LIBDIR ${CMAKE_INSTALL_LIBDIR}/unity8)
61+
62+execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=plugindir_suffix unity-shell-api OUTPUT_VARIABLE SHELL_INSTALL_QML OUTPUT_STRIP_TRAILING_WHITESPACE)
63+if(SHELL_INSTALL_QML STREQUAL "")
64+ message(FATAL_ERROR "Could not determine plugin installation dir.")
65+endif()
66+
67+execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=plugindir unity-shell-api OUTPUT_VARIABLE SHELL_PLUGINDIR OUTPUT_STRIP_TRAILING_WHITESPACE)
68+if(SHELL_PLUGINDIR STREQUAL "")
69+ message(FATAL_ERROR "Could not determine plugin import dir.")
70+endif()
62
71
63configure_file(paths.h.in ${CMAKE_CURRENT_BINARY_DIR}/paths.h @ONLY)
72configure_file(paths.h.in ${CMAKE_CURRENT_BINARY_DIR}/paths.h @ONLY)
64
73
Components/Carousel.qml+4−6
@@ -54,15 +54,13 @@ Item {
54
54
55 /// Emitted when the user clicked on an item
55 /// Emitted when the user clicked on an item
56 /// @param index is the index of the clicked item
56 /// @param index is the index of the clicked item
57− /// @param model is the model of all the items in the carousel
58 /// @param itemY is y of the clicked delegate
57 /// @param itemY is y of the clicked delegate
59− signal clicked(int index, var model, real itemY)
58+ signal clicked(int index, real itemY)
60
59
61 /// Emitted when the user pressed and held on an item
60 /// Emitted when the user pressed and held on an item
62 /// @param index is the index of the held item
61 /// @param index is the index of the held item
63− /// @param model is the model of all the items in the carousel
64 /// @param itemY is y of the held delegate
62 /// @param itemY is y of the held delegate
65− signal pressAndHold(int index, var model, real itemY)
63+ signal pressAndHold(int index, real itemY)
66
64
67 implicitHeight: listView.tileHeight * selectedItemScaleFactor
65 implicitHeight: listView.tileHeight * selectedItemScaleFactor
68
66
@@ -163,7 +161,7 @@ Item {
163 /* We're clicking the selected item and
161 /* We're clicking the selected item and
164 we're in the neighbourhood of radius 1 pixel from it.
162 we're in the neighbourhood of radius 1 pixel from it.
165 Let's emit the clicked signal. */
163 Let's emit the clicked signal. */
166− carousel.clicked(index, listView.model, delegateItem.y)
164+ carousel.clicked(index, delegateItem.y)
167 return
165 return
168 }
166 }
169
167
@@ -187,7 +185,7 @@ Item {
187 /* We're pressAndHold the selected item and
185 /* We're pressAndHold the selected item and
188 we're in the neighbourhood of radius 1 pixel from it.
186 we're in the neighbourhood of radius 1 pixel from it.
189 Let's emit the pressAndHold signal. */
187 Let's emit the pressAndHold signal. */
190− carousel.pressAndHold(index, listView.model, delegateItem.y);
188+ carousel.pressAndHold(index, delegateItem.y);
191 return;
189 return;
192 }
190 }
193
191
Components/DragHandle.qml+22−24
@@ -17,7 +17,6 @@
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19import Ubuntu.Gestures 0.1
19import Ubuntu.Gestures 0.1
20−import "Math.js" as MathLocal
21
20
22/*
21/*
23 Put a DragHandle inside a Showable to enable the user to drag it from that handle.
22 Put a DragHandle inside a Showable to enable the user to drag it from that handle.
@@ -48,9 +47,12 @@ EdgeDragArea {
48 id: dragArea
47 id: dragArea
49 objectName: "dragHandle"
48 objectName: "dragHandle"
50
49
51− // Disable gesture detection by default when hinting is used.
50+ // Disable most of the gesture recognition parameters by default when hinting is used as
52− // It doesn't make sense to have both.
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 : units.gu(1.5)
53+ distanceThreshold: hintDisplacement > 0 ? 0 : defaultDistanceThreshold
54+ maxSilenceTime: hintDisplacement > 0 ? 60*60*1000 : defaultMaxSilenceTime
55+ maxDeviation: hintDisplacement > 0 ? 999999 : defaultMaxDeviation
54
56
55 property bool stretch: false
57 property bool stretch: false
56
58
@@ -113,8 +115,8 @@ EdgeDragArea {
113 }
115 }
114 }
116 }
115
117
116− function limitMovement(step) {
118+ function limitMovement(inputStep) {
117− var targetValue = MathLocal.clamp(dragParent[targetProp] + step, minValue, maxValue);
119+ var targetValue = MathUtils.clamp(dragParent[targetProp] + inputStep, minValue, maxValue);
118 var step = targetValue - dragParent[targetProp];
120 var step = targetValue - dragParent[targetProp];
119
121
120 if (hintDisplacement == 0) {
122 if (hintDisplacement == 0) {
@@ -181,29 +183,25 @@ EdgeDragArea {
181 }
183 }
182 }
184 }
183
185
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−
195 onStatusChanged: {
186 onStatusChanged: {
196 if (status === DirectionalDragArea.WaitingForTouch) {
187 if (status === DirectionalDragArea.WaitingForTouch) {
188+ hintingAnimation.stop();
197 if (d.previousStatus === DirectionalDragArea.Recognized) {
189 if (d.previousStatus === DirectionalDragArea.Recognized) {
198 d.onFinishedRecognizedGesture();
190 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();
199 }
204 }
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];
207 }
205 }
208
206
209 d.previousStatus = status;
207 d.previousStatus = status;
Components/DraggingArea.qml+1−2
@@ -16,7 +16,6 @@
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19−import "Math.js" as MathLocal
20
19
21MouseArea {
20MouseArea {
22 id: draggingArea
21 id: draggingArea
@@ -26,7 +25,7 @@ MouseArea {
26 property real dragVelocity: 0
25 property real dragVelocity: 0
27 property real dragValue: (orientation == Qt.Vertical ? (mouseY - __pressedPosition.y)
26 property real dragValue: (orientation == Qt.Vertical ? (mouseY - __pressedPosition.y)
28 : (mouseX - __pressedPosition.x))
27 : (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)
30 property point __pressedPosition: Qt.point(0, 0)
29 property point __pressedPosition: Qt.point(0, 0)
31 property var __dragEvents: []
30 property var __dragEvents: []
32 property bool clickValidated: true
31 property bool clickValidated: true
Components/EdgeDemoOverlay.qml+2
@@ -105,6 +105,8 @@ Showable {
105 visible: overlay.active
105 visible: overlay.active
106
106
107 MouseArea {
107 MouseArea {
108+ objectName: "backgroundShadeMouseArea"
109+
108 anchors.fill: parent
110 anchors.fill: parent
109 enabled: overlay.edge == "none" && overlay.opacity == 1.0
111 enabled: overlay.edge == "none" && overlay.opacity == 1.0
110 onClicked: overlay.doSkip()
112 onClicked: overlay.doSkip()
Components/EdgeDragArea.qml+12−4
@@ -29,8 +29,16 @@ DirectionalDragArea {
29 //
29 //
30 // The idea here is that it's better having lax rules than false negatives.
30 // The idea here is that it's better having lax rules than false negatives.
31 // False negatives are very frustrating to the user.
31 // False negatives are very frustrating to the user.
32− maxDeviation: units.gu(3)
32+ maxDeviation: defaultMaxDeviation
33− wideningAngle: 50
33+ wideningAngle: defaultWideningAngle
34− distanceThreshold: units.gu(1.5)
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)
35− minSpeed: units.gu(0) // some people were getting false negatives with it enabled.
41+ // some people were getting false negatives with it enabled.
42+ readonly property real defaultMinSpeed: units.gu(0)
43+ readonly property int defaultMaxSilenceTime: 200
36}
44}
Components/PageHeader.qml+26−7
@@ -30,7 +30,7 @@ Item {
30
30
31 property bool searchEntryEnabled: false
31 property bool searchEntryEnabled: false
32 property alias searchQuery: searchField.text
32 property alias searchQuery: searchField.text
33− property ListModel searchHistory: SearchHistoryModel {}
33+ property ListModel searchHistory
34 property Scope scope
34 property Scope scope
35
35
36 height: units.gu(8.5)
36 height: units.gu(8.5)
@@ -44,8 +44,8 @@ Item {
44 if (!searchHistory) return;
44 if (!searchHistory) return;
45
45
46 searchHistory.addQuery(searchField.text);
46 searchHistory.addQuery(searchField.text);
47+ unfocus();
47 searchField.text = "";
48 searchField.text = "";
48− searchField.focus = false;
49 }
49 }
50
50
51 function unfocus() {
51 function unfocus() {
@@ -112,6 +112,8 @@ Item {
112 objectName: "searchContainer"
112 objectName: "searchContainer"
113
113
114 visible: searchEntryEnabled
114 visible: searchEntryEnabled
115+ property bool popoverShouldOpen: false
116+ property bool popoverShouldClose: false
115
117
116 property bool narrowMode: parent.width < label.contentWidth + units.gu(50)
118 property bool narrowMode: parent.width < label.contentWidth + units.gu(50)
117
119
@@ -127,6 +129,16 @@ Item {
127 else if (active && !narrowMode) "active"
129 else if (active && !narrowMode) "active"
128 else if (!active && !narrowMode) "inactive"
130 else if (!active && !narrowMode) "inactive"
129
131
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+
130 function openPopover() {
142 function openPopover() {
131 if (searchHistory.count > 0) {
143 if (searchHistory.count > 0) {
132 searchContainer.popover = PopupUtils.open(popoverComponent, searchField,
144 searchContainer.popover = PopupUtils.open(popoverComponent, searchField,
@@ -137,10 +149,17 @@ Item {
137 }
149 }
138 )
150 )
139 }
151 }
152+ popoverShouldOpen = false;
153+ popoverShouldClose = false;
140 }
154 }
141
155
142 function closePopover() {
156 function closePopover() {
157+ if (searchContainer.popover) {
143− if (searchContainer.popover) PopupUtils.close(searchContainer.popover)
158+ PopupUtils.close(searchContainer.popover);
159+ searchContainer.popover = null;
160+ }
161+ popoverShouldOpen = false;
162+ popoverShouldClose = false;
144 }
163 }
145
164
146 onActiveFocusChanged: if (!activeFocus) { searchHistory.addQuery(searchField.text) }
165 onActiveFocusChanged: if (!activeFocus) { searchHistory.addQuery(searchField.text) }
@@ -283,12 +302,12 @@ Item {
283 PropertyAction { target: primaryImage; property: "source" }
302 PropertyAction { target: primaryImage; property: "source" }
284 AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
303 AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
285 }
304 }
286− ScriptAction { script: searchContainer.openPopover() }
305+ ScriptAction { script: if (searchContainer.popoverShouldOpen) { searchContainer.openPopover(); } }
287 }
306 }
288 },
307 },
289 Transition {
308 Transition {
290 to: "inactive"
309 to: "inactive"
291− ScriptAction { script: searchContainer.closePopover() }
310+ ScriptAction { script: if (searchContainer.popoverShouldClose) { searchContainer.closePopover(); } }
292 NumberAnimation { targets: [searchContainer, searchField] ; property: "width"; duration: 200; easing.type: Easing.InOutQuad }
311 NumberAnimation { targets: [searchContainer, searchField] ; property: "width"; duration: 200; easing.type: Easing.InOutQuad }
293 AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
312 AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
294 },
313 },
@@ -299,12 +318,12 @@ Item {
299 NumberAnimation { targets: [searchContainer, searchField] ; property: "width"; duration: 200; easing.type: Easing.OutQuad }
318 NumberAnimation { targets: [searchContainer, searchField] ; property: "width"; duration: 200; easing.type: Easing.OutQuad }
300 AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
319 AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
301 }
320 }
302− ScriptAction { script: searchContainer.openPopover() }
321+ ScriptAction { script: if (searchContainer.popoverShouldOpen) { searchContainer.openPopover(); } }
303 }
322 }
304 },
323 },
305 Transition {
324 Transition {
306 to: "narrowInactive"
325 to: "narrowInactive"
307− ScriptAction { script: searchContainer.closePopover() }
326+ ScriptAction { script: if (searchContainer.popoverShouldClose) { searchContainer.closePopover(); } }
308 NumberAnimation { targets: [searchContainer, searchField] ; property: "width"; duration: 200; easing.type: Easing.OutQuad }
327 NumberAnimation { targets: [searchContainer, searchField] ; property: "width"; duration: 200; easing.type: Easing.OutQuad }
309 AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
328 AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
310 }
329 }
Components/PinPadButton.qml+40−13
@@ -21,24 +21,51 @@ Item {
21 id: root
21 id: root
22
22
23 property alias text: label.text
23 property alias text: label.text
24− property alias iconName: icon.name
24+ property alias subText: subTextLabel.text
25+ property string iconName
25
26
26 signal clicked()
27 signal clicked()
27
28
28− Label {
29+ Column {
29− id: label
30 anchors.centerIn: parent
30 anchors.centerIn: parent
31− color: "#f3f3e7"
31+ width: parent.width
32− fontSize: "large"
32+ height: childrenRect.height
33− font.weight: Font.DemiBold
34− }
35
33
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+
36− Icon {
52+ Icon {
37− id: icon
53+ id: icon
38− height: units.gu(3)
54+ height: units.gu(3)
39− width: height
55+ width: height
40− anchors.centerIn: parent
56+ anchors.centerIn: parent
57+ name: root.iconName
41− color: "#f3f3e7"
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+ }
42 }
69 }
43
70
44 MouseArea {
71 MouseArea {
Components/Revealer.qml+1−2
@@ -16,7 +16,6 @@
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19−import "Math.js" as MathLocal
20
19
21Item {
20Item {
22 id: revealer
21 id: revealer
@@ -95,7 +94,7 @@ Item {
95 onClosedValueChanged: if (!__opened && !dragging) target[boundProperty] = closedValue
94 onClosedValueChanged: if (!__opened && !dragging) target[boundProperty] = closedValue
96
95
97 function __computeValue(dragPosition) {
96 function __computeValue(dragPosition) {
98− return MathLocal.clamp(dragToValue(dragPosition), __hintValue, openedValue)
97+ return MathUtils.clamp(dragToValue(dragPosition), __hintValue, openedValue)
99 }
98 }
100
99
101 function __open() {
100 function __open() {
Components/Stage.qml+8−7
@@ -482,19 +482,20 @@ Showable {
482 switchToApplicationAnimationController.progress += 0.4 * delta
482 switchToApplicationAnimationController.progress += 0.4 * delta
483 }
483 }
484
484
485− property bool gotRejected: false
485+ property int lastStatus: -1
486
486
487 onStatusChanged: {
487 onStatusChanged: {
488 if (status == DirectionalDragArea.Undecided) {
488 if (status == DirectionalDragArea.Undecided) {
489− gotRejected = false
490 onUndecided();
489 onUndecided();
491− } else if (status == DirectionalDragArea.Rejected) {
492− switchToApplicationAnimationController.completeToBeginningWithSignal();
493− gotRejected = true;
494 } else if (status == DirectionalDragArea.WaitingForTouch) {
490 } else if (status == DirectionalDragArea.WaitingForTouch) {
495− if (!gotRejected)
491+ if (lastStatus == DirectionalDragArea.Undecided) {
492+ // got rejected
493+ switchToApplicationAnimationController.completeToBeginningWithSignal();
494+ } else {
496− onGestureEnded()
495+ onGestureEnded();
496+ }
497 }
497 }
498+ lastStatus = status;
498 }
499 }
499
500
500 function onUndecided() {
501 function onUndecided() {
Components/Time.jsdeleted−49
@@ -1,49 +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−.pragma library
18−
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−}
28−
29−function readableFromNow(date, now) {
30− var then = new Date(date);
31− if (isNaN(then)) return "";
32− if (now === undefined) {
33− now = new Date();
34− } else if (isNaN(now)) throw "now is NaN";
35− var diff = Math.abs(now - then);
36− if (diff < 1000) return "just now";
37−
38− var future = now < then;
39− var humanDiff;
40− for (var k in factors) {
41− diff /= factors[k][0];
42− if (Math.floor(diff) == 1) {
43− humanDiff = factors[k][future ? 2 : 1];
44− } else if (Math.floor(diff) > 1) {
45− humanDiff = factors[k][future ? 4 : 3].arg(Math.round(diff));
46− } else break;
47− }
48− return humanDiff;
49−}
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 {
37 }
37 }
38
38
39 onClicked: {
39 onClicked: {
40− filtergrid.clicked(index, filtergrid.model, tile.y)
40+ filtergrid.clicked(index, tile.y)
41 }
41 }
42
42
43 onPressAndHold: {
43 onPressAndHold: {
44− filtergrid.pressAndHold(index, filtergrid.model, tile.y)
44+ filtergrid.pressAndHold(index, tile.y)
45 }
45 }
46 }
46 }
47}
47}
Dash/Apps/RunningApplicationTile.qml−2
@@ -105,8 +105,6 @@ AbstractButton {
105 baseline: parent.bottom
105 baseline: parent.bottom
106 left: parent.left
106 left: parent.left
107 right: parent.right
107 right: parent.right
108− leftMargin: units.gu(1)
109− rightMargin: units.gu(1)
110 }
108 }
111 text: (application) ? application.name : ""
109 text: (application) ? application.name : ""
112
110
Dash/Dash.qml+3
@@ -26,6 +26,8 @@ Showable {
26
26
27 visible: shown
27 visible: shown
28
28
29+ property ListModel searchHistory: SearchHistoryModel {}
30+
29 property alias contentProgress: dashContent.contentProgress
31 property alias contentProgress: dashContent.contentProgress
30 property string showScopeOnLoaded: "home.scope"
32 property string showScopeOnLoaded: "home.scope"
31 property real contentScale: 1.0
33 property real contentScale: 1.0
@@ -63,6 +65,7 @@ Showable {
63 anchors.fill: parent
65 anchors.fill: parent
64 model: filteredScopes
66 model: filteredScopes
65 scopes: scopes
67 scopes: scopes
68+ searchHistory: dash.searchHistory
66 onMovementStarted: dashbar.startNavigation()
69 onMovementStarted: dashbar.startNavigation()
67 onMovementEnded: dashbar.stopNavigation()
70 onMovementEnded: dashbar.stopNavigation()
68 onContentFlickStarted: dashbar.finishNavigation()
71 onContentFlickStarted: dashbar.finishNavigation()
Dash/DashApps.qml+3
@@ -30,6 +30,9 @@ GenericScopeView {
30 property var mainStageApplicationsModel: shell.applicationManager.mainStageApplications
30 property var mainStageApplicationsModel: shell.applicationManager.mainStageApplications
31 property var sideStageApplicationModel: shell.applicationManager.sideStageApplications
31 property var sideStageApplicationModel: shell.applicationManager.sideStageApplications
32
32
33+ //FIXME an alias to itself shouldn't be required. More than likely a Qt bug. Try removing with newer Qt.
34+ property alias searchHistory: scopeView.searchHistory
35+
33 ListModel {
36 ListModel {
34 id: dummyVisibilityModifier
37 id: dummyVisibilityModifier
35
38
Dash/DashContent.qml+2−1
@@ -27,6 +27,7 @@ Item {
27 property alias currentIndex: dashContentList.currentIndex
27 property alias currentIndex: dashContentList.currentIndex
28
28
29 property ScopeDelegateMapper scopeMapper : ScopeDelegateMapper {}
29 property ScopeDelegateMapper scopeMapper : ScopeDelegateMapper {}
30+ property ListModel searchHistory
30
31
31 signal movementStarted()
32 signal movementStarted()
32 signal movementEnded()
33 signal movementEnded()
@@ -127,7 +128,7 @@ Item {
127 onLoaded: {
128 onLoaded: {
128 item.scope = Qt.binding(function() { return scope })
129 item.scope = Qt.binding(function() { return scope })
129 item.isCurrent = Qt.binding(function() { return visible && ListView.isCurrentItem })
130 item.isCurrent = Qt.binding(function() { return visible && ListView.isCurrentItem })
130− item.searchHistory = Qt.binding(function() { return shell.searchHistory })
131+ item.searchHistory = Qt.binding(function() { return dashContent.searchHistory })
131 dashContentList.movementStarted.connect(item.movementStarted)
132 dashContentList.movementStarted.connect(item.movementStarted)
132 dashContent.positionedAtBeginning.connect(item.positionedAtBeginning)
133 dashContent.positionedAtBeginning.connect(item.positionedAtBeginning)
133 dashContent.scopeLoaded(item.scope.id)
134 dashContent.scopeLoaded(item.scope.id)
Components/Math.js → Dash/Generic/GenericCarouselLoader.qmlrenamed+11−7
@@ -14,13 +14,17 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−.pragma library
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
18
19
19−function clamp(value, min, max) {
20+Loader {
20− if (min <= max) {
21+ property var model: null
21− return Math.max(min, Math.min(max, value))
22+ property url carouselUrl: "GenericCarousel.qml"
22− } else {
23+ property url filtergridUrl: "GenericFilterGrid.qml"
23− // swap min/max if min > max
24+
24− return clamp(value, max, min)
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; })
25 }
29 }
26}
30}
Dash/Generic/GenericFilterGrid.qml+4−4
@@ -28,8 +28,8 @@ FilterGrid {
28 property int iconWidth: units.gu(8)
28 property int iconWidth: units.gu(8)
29 property int iconHeight: units.gu(7.5)
29 property int iconHeight: units.gu(7.5)
30
30
31− signal clicked(int index, var model, real itemY)
31+ signal clicked(int index, real itemY)
32− signal pressAndHold(int index, var model, real itemY)
32+ signal pressAndHold(int index, real itemY)
33
33
34 delegate: Tile {
34 delegate: Tile {
35 id: tile
35 id: tile
@@ -42,11 +42,11 @@ FilterGrid {
42 source: model.icon
42 source: model.icon
43
43
44 onClicked: {
44 onClicked: {
45− filtergrid.clicked(index, filtergrid.model, tile.y)
45+ filtergrid.clicked(index, tile.y)
46 }
46 }
47
47
48 onPressAndHold: {
48 onPressAndHold: {
49− filtergrid.pressAndHold(index, filtergrid.model, tile.y)
49+ filtergrid.pressAndHold(index, tile.y)
50 }
50 }
51 }
51 }
52}
52}
Dash/Generic/WeatherFilterGrid.qml+2−2
@@ -37,11 +37,11 @@ GenericFilterGrid {
37 style: FlatTileStyle {}
37 style: FlatTileStyle {}
38
38
39 onClicked: {
39 onClicked: {
40− filtergrid.clicked(index, filtergrid.model, tile.y)
40+ filtergrid.clicked(index, tile.y)
41 }
41 }
42
42
43 onPressAndHold: {
43 onPressAndHold: {
44− filtergrid.pressAndHold(index, filtergrid.model, tile.y)
44+ filtergrid.pressAndHold(index, tile.y)
45 }
45 }
46 }
46 }
47}
47}
Dash/GenericScopeView.qml+73−19
@@ -16,15 +16,60 @@
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19+import Utils 0.1
20+import Unity 0.1
19import "../Components"
21import "../Components"
20import "../Components/ListItems" as ListItems
22import "../Components/ListItems" as ListItems
21
23
22−ScopeView {
24+FocusScope {
23 id: scopeView
25 id: scopeView
26+
27+ property Scope scope
28+ property SortFilterProxyModel categories: categoryFilter
29+ property bool isCurrent
30+ property ListModel searchHistory
31+ property alias moving: categoryView.moving
32+
33+ signal endReached
34+ signal movementStarted
35+ signal positionedAtBeginning
36+
24 readonly property alias previewShown: previewListView.onScreen
37 readonly property alias previewShown: previewListView.onScreen
25 property bool enableHeightBehaviorOnNextCreation: false
38 property bool enableHeightBehaviorOnNextCreation: false
26
39
27− 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+ }
28
73
29 onIsCurrentChanged: {
74 onIsCurrentChanged: {
30 pageHeader.resetSearch();
75 pageHeader.resetSearch();
@@ -130,14 +175,14 @@ ScopeView {
130 target: rendererLoader.item
175 target: rendererLoader.item
131 onClicked: {
176 onClicked: {
132 // Prepare the preview in case activate() triggers a preview only
177 // Prepare the preview in case activate() triggers a preview only
133− effect.positionPx = mapToItem(categoryView, 0, itemY).y
178+ effect.positionPx = Math.max(mapToItem(categoryView, 0, itemY).y, pageHeader.height + categoryView.stickyHeaderHeight);
134 previewListView.categoryId = categoryId
179 previewListView.categoryId = categoryId
135 previewListView.categoryDelegate = rendererLoader.item
180 previewListView.categoryDelegate = rendererLoader.item
136− previewListView.model = model;
181+ previewListView.model = target.model;
137 previewListView.init = true;
182 previewListView.init = true;
138 previewListView.currentIndex = index;
183 previewListView.currentIndex = index;
139
184
140− var item = model.get(index);
185+ var item = target.model.get(index);
141
186
142 if ((scopeView.scope.id == "applications.scope" && categoryId == "installed")
187 if ((scopeView.scope.id == "applications.scope" && categoryId == "installed")
143 || (scopeView.scope.id == "home.scope" && categoryId == "applications.scope")) {
188 || (scopeView.scope.id == "home.scope" && categoryId == "applications.scope")) {
@@ -151,15 +196,15 @@ ScopeView {
151 }
196 }
152 }
197 }
153 onPressAndHold: {
198 onPressAndHold: {
154− effect.positionPx = mapToItem(categoryView, 0, itemY).y
199+ effect.positionPx = Math.max(mapToItem(categoryView, 0, itemY).y, pageHeader.height + categoryView.stickyHeaderHeight);
155 previewListView.categoryId = categoryId
200 previewListView.categoryId = categoryId
156 previewListView.categoryDelegate = rendererLoader.item
201 previewListView.categoryDelegate = rendererLoader.item
157− previewListView.model = model;
202+ previewListView.model = target.model;
158 previewListView.init = true;
203 previewListView.init = true;
159 previewListView.currentIndex = index;
204 previewListView.currentIndex = index;
160 previewListView.open = true
205 previewListView.open = true
161
206
162− var item = model.get(index)
207+ var item = target.model.get(index)
163 scopeView.scope.preview( item.uri, item.icon, item.category, 0, item.mimetype, item.title,
208 scopeView.scope.preview( item.uri, item.icon, item.category, 0, item.mimetype, item.title,
164 item.comment, item.dndUri, item.metadata)
209 item.comment, item.dndUri, item.metadata)
165 }
210 }
@@ -248,6 +293,7 @@ ScopeView {
248 text: scopeView.scope.name
293 text: scopeView.scope.name
249 searchEntryEnabled: true
294 searchEntryEnabled: true
250 scope: scopeView.scope
295 scope: scopeView.scope
296+ searchHistory: scopeView.searchHistory
251 }
297 }
252 }
298 }
253
299
@@ -262,26 +308,27 @@ ScopeView {
262 rendererId = getDefaultRendererId(contentType);
308 rendererId = getDefaultRendererId(contentType);
263 }
309 }
264 switch (rendererId) {
310 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+ }
265 case "grid": {
318 case "grid": {
266 switch (contentType) {
319 switch (contentType) {
267− case "video": return "Video/VideoFilterGrid.qml";
268− case "music": return "Music/MusicFilterGrid.qml";
269 case "apps": {
320 case "apps": {
270 if (rendererHint == "toggled")
321 if (rendererHint == "toggled")
271 return "Apps/DashPluginFilterGrid.qml";
322 return "Apps/DashPluginFilterGrid.qml";
272 else
323 else
273 return "Generic/GenericFilterGrid.qml";
324 return "Generic/GenericFilterGrid.qml";
274 }
325 }
326+ case "music": return "Music/MusicFilterGrid.qml";
327+ case "video": return "Video/VideoFilterGrid.qml";
275 case "weather": return "Generic/WeatherFilterGrid.qml";
328 case "weather": return "Generic/WeatherFilterGrid.qml";
276 default: return "Generic/GenericFilterGrid.qml";
329 default: return "Generic/GenericFilterGrid.qml";
277 }
330 }
278 }
331 }
279− case "carousel": {
280− switch (contentType) {
281− case "music": return "Music/MusicCarousel.qml";
282− default: return "Generic/GenericCarousel.qml";
283− }
284− }
285 case "special": {
332 case "special": {
286 switch (contentType) {
333 switch (contentType) {
287 case "apps": return "Apps/RunningApplicationsGrid.qml";
334 case "apps": return "Apps/RunningApplicationsGrid.qml";
@@ -392,12 +439,19 @@ ScopeView {
392
439
393 if (!init && model !== undefined) {
440 if (!init && model !== undefined) {
394 var item = model.get(currentIndex)
441 var item = model.get(currentIndex)
395− 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)
396 }
443 }
397
444
398 var itemY = categoryView.contentItem.mapFromItem(categoryDelegate.currentItem).y;
445 var itemY = categoryView.contentItem.mapFromItem(categoryDelegate.currentItem).y;
446+
447+ // Find new contentY and effect.postionPx
399 var newContentY = itemY - effect.positionPx - categoryDelegate.verticalSpacing;
448 var newContentY = itemY - effect.positionPx - categoryDelegate.verticalSpacing;
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;
400− var effectAdjust = effect.positionPx;
452+ var effectAdjust = Math.max(effect.positionPx, headerHeight);
453+
454+ // Make sure we don't overscroll the listview. If yes, adjust effect position
401 if (newContentY < 0) {
455 if (newContentY < 0) {
402 effectAdjust += newContentY;
456 effectAdjust += newContentY;
403 newContentY = 0;
457 newContentY = 0;
@@ -408,7 +462,7 @@ ScopeView {
408 }
462 }
409
463
410 effect.positionPx = effectAdjust;
464 effect.positionPx = effectAdjust;
411− categoryView.contentY = newContentY - categoryView.originY;
465+ categoryView.contentY = newContentY;
412 }
466 }
413
467
414 property bool open: false
468 property bool open: false
tests/mocks/QMenuModel/UnityMenuModel.qml → Dash/Music/MusicCarouselLoader.qmlrenamed+5−7
@@ -1,9 +1,6 @@
1/*
1/*
2 * Copyright (C) 2013 Canonical, Ltd.
2 * Copyright (C) 2013 Canonical, Ltd.
3 *
3 *
4− * Authors:
5− * Mirco Müller <mirco.mueller@canonical.com>
6− *
7 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 3.
6 * the Free Software Foundation; version 3.
@@ -18,9 +15,10 @@
18 */
15 */
19
16
20import QtQuick 2.0
17import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import "../Generic"
21
20
22−QtObject {
21+GenericCarouselLoader {
23− property variant busName
22+ carouselUrl: "MusicCarousel.qml"
24− property variant actions
23+ filtergridUrl: "MusicFilterGrid.qml"
25− property variant menuObjectPath
26}
24}
Dash/Music/MusicFilterGrid.qml+2−2
@@ -44,11 +44,11 @@ GenericFilterGrid {
44 }
44 }
45
45
46 onClicked: {
46 onClicked: {
47− filtergrid.clicked(index, filtergrid.model, tile.y)
47+ filtergrid.clicked(index, tile.y)
48 }
48 }
49
49
50 onPressAndHold: {
50 onPressAndHold: {
51− filtergrid.pressAndHold(index, filtergrid.model, tile.y)
51+ filtergrid.pressAndHold(index, tile.y)
52 }
52 }
53 }
53 }
54}
54}
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.

plugins/Unity/abstractfilteroption.cpp → Dash/Video/VideoCarouselLoader.qmlrenamed+6−7
@@ -1,9 +1,6 @@
1/*
1/*
2 * Copyright (C) 2013 Canonical, Ltd.
2 * Copyright (C) 2013 Canonical, Ltd.
3 *
3 *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 3.
6 * the Free Software Foundation; version 3.
@@ -17,9 +14,11 @@
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
15 */
19
16
20−#include "abstractfilteroption.h"
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import "../Generic"
21
20
22−AbstractFilterOption::AbstractFilterOption(QObject *parent)
21+GenericCarouselLoader {
23− : QObject(parent)
22+ carouselUrl: "VideoCarousel.qml"
24−{
23+ filtergridUrl: "VideoFilterGrid.qml"
25}
24}
Dash/Video/VideoFilterGrid.qml+2−2
@@ -42,11 +42,11 @@ GenericFilterGrid {
42 style: VideoTileStyle {}
42 style: VideoTileStyle {}
43
43
44 onClicked: {
44 onClicked: {
45− filtergrid.clicked(index, filtergrid.model, tile.y)
45+ filtergrid.clicked(index, tile.y)
46 }
46 }
47
47
48 onPressAndHold: {
48 onPressAndHold: {
49− filtergrid.pressAndHold(index, filtergrid.model, tile.y)
49+ filtergrid.pressAndHold(index, tile.y)
50 }
50 }
51 }
51 }
52}
52}
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+4−7
@@ -19,7 +19,6 @@ import Ubuntu.Components 0.1
19import Ubuntu.Gestures 0.1
19import Ubuntu.Gestures 0.1
20import LightDM 0.1 as LightDM
20import LightDM 0.1 as LightDM
21import "../Components"
21import "../Components"
22−import "../Components/Math.js" as MathLocal
23
22
24Showable {
23Showable {
25 id: greeter
24 id: greeter
@@ -29,7 +28,7 @@ Showable {
29 property url defaultBackground
28 property url defaultBackground
30
29
31 // 1 when fully shown and 0 when fully hidden
30 // 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)
33
32
34 showAnimation: StandardAnimation { property: "x"; to: 0 }
33 showAnimation: StandardAnimation { property: "x"; to: 0 }
35 hideAnimation: StandardAnimation { property: "x"; to: -width }
34 hideAnimation: StandardAnimation { property: "x"; to: -width }
@@ -64,6 +63,7 @@ Showable {
64 property var model: LightDM.Users
63 property var model: LightDM.Users
65 property int currentIndex: 0
64 property int currentIndex: 0
66 property var infographicModel: LightDM.Infographic
65 property var infographicModel: LightDM.Infographic
66+ readonly property int backgroundTopMargin: -greeter.y
67
67
68 source: required ? "GreeterContent.qml" : ""
68 source: required ? "GreeterContent.qml" : ""
69
69
@@ -89,7 +89,7 @@ Showable {
89 when: teasingTimer.running
89 when: teasingTimer.running
90 PropertyChanges {
90 PropertyChanges {
91 target: greeter
91 target: greeter
92− x: -units.gu(2)
92+ x: -dragHandle.hintDisplacement
93 }
93 }
94 }
94 }
95 ]
95 ]
@@ -113,10 +113,7 @@ Showable {
113 anchors.bottom: parent.bottom
113 anchors.bottom: parent.bottom
114 anchors.right: parent.right
114 anchors.right: parent.right
115
115
116− // no need for requiring a directional drag since we are covering the screen
116+ hintDisplacement: units.gu(2)
117− // anyway (i.e., no change user could be trying to interact with some other
118− // UI element)
119− distanceThreshold: 0
120
117
121 enabled: greeter.narrowMode || !greeter.locked
118 enabled: greeter.narrowMode || !greeter.locked
122
119
Greeter/GreeterContent.qml+23−20
@@ -24,7 +24,7 @@ MouseArea {
24 id: root
24 id: root
25 anchors.fill: parent
25 anchors.fill: parent
26
26
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
28 property bool leftTeaserPressed: teasingMouseArea.pressed &&
28 property bool leftTeaserPressed: teasingMouseArea.pressed &&
29 teasingMouseArea.mouseX < teasingMouseArea.width / 2
29 teasingMouseArea.mouseX < teasingMouseArea.width / 2
30 property bool rightTeaserPressed: teasingMouseArea.pressed &&
30 property bool rightTeaserPressed: teasingMouseArea.pressed &&
@@ -34,33 +34,36 @@ MouseArea {
34 signal unlocked(int uid)
34 signal unlocked(int uid)
35
35
36 Rectangle {
36 Rectangle {
37− // In case wallpaper fails to load
37+ // In case background fails to load
38− id: wallpaperBackup
38+ id: backgroundBackup
39 anchors.fill: parent
39 anchors.fill: parent
40 color: "black"
40 color: "black"
41 }
41 }
42
42
43 property url backgroundValue: AccountsService.backgroundFile != undefined && AccountsService.backgroundFile.length > 0 ? AccountsService.backgroundFile : greeter.defaultBackground
43 property url backgroundValue: AccountsService.backgroundFile != undefined && AccountsService.backgroundFile.length > 0 ? AccountsService.backgroundFile : greeter.defaultBackground
44− onBackgroundValueChanged: wallpaper.source = backgroundValue
44+ onBackgroundValueChanged: background.source = backgroundValue
45
45
46 CrossFadeImage {
46 CrossFadeImage {
47− id: wallpaper
47+ id: background
48− objectName: "wallpaper"
48+ objectName: "greeterBackground"
49+ anchors {
49− anchors.fill: parent
50+ fill: parent
51+ topMargin: backgroundTopMargin
52+ }
50 fillMode: Image.PreserveAspectCrop
53 fillMode: Image.PreserveAspectCrop
51 }
54 }
52
55
53 // See Shell.qml's backgroundSettings treatment for why we need a separate
56 // See Shell.qml's backgroundSettings treatment for why we need a separate
54 // Image, but it boils down to avoiding binding loop detection.
57 // Image, but it boils down to avoiding binding loop detection.
55 Image {
58 Image {
56− source: wallpaper.source
59+ source: background.source
57 height: 0
60 height: 0
58 width: 0
61 width: 0
59 sourceSize.height: 0
62 sourceSize.height: 0
60 sourceSize.width: 0
63 sourceSize.width: 0
61 onStatusChanged: {
64 onStatusChanged: {
62 if (status == Image.Error && source != greeter.defaultBackground) {
65 if (status == Image.Error && source != greeter.defaultBackground) {
63− wallpaper.source = greeter.defaultBackground
66+ background.source = greeter.defaultBackground
64 }
67 }
65 }
68 }
66 }
69 }
@@ -71,17 +74,6 @@ MouseArea {
71 opacity: 0.4
74 opacity: 0.4
72 }
75 }
73
76
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−
85 MouseArea {
77 MouseArea {
86 id: teasingMouseArea
78 id: teasingMouseArea
87 anchors.fill: parent
79 anchors.fill: parent
@@ -160,4 +152,15 @@ MouseArea {
160 right: root.right
152 right: root.right
161 }
153 }
162 }
154 }
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+ }
163}
166}
Greeter/Lockscreen.qml+14−22
@@ -17,7 +17,6 @@
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19import "../Components"
19import "../Components"
20−import LightDM 0.1 as LightDM
21
20
22Showable {
21Showable {
23 id: root
22 id: root
@@ -37,7 +36,7 @@ Showable {
37
36
38 property url background: ""
37 property url background: ""
39
38
40− signal unlocked()
39+ signal entered(string passphrase)
41 signal cancel()
40 signal cancel()
42 signal emergencyCall()
41 signal emergencyCall()
43
42
@@ -53,16 +52,24 @@ Showable {
53 pinPadLoader.resetting = false;
52 pinPadLoader.resetting = false;
54 }
53 }
55
54
55+ function clear(showAnimation) {
56+ pinPadLoader.item.clear(showAnimation);
57+ }
58+
56 Rectangle {
59 Rectangle {
57− // In case wallpaper fails to load or is undefined
60+ // In case background fails to load or is undefined
58− id: wallpaperBackup
61+ id: backgroundBackup
59 anchors.fill: parent
62 anchors.fill: parent
60 color: "black"
63 color: "black"
61 }
64 }
62
65
63 Image {
66 Image {
64− id: wallpaper
67+ id: backgroundImage
68+ objectName: "lockscreenBackground"
69+ anchors {
65− anchors.fill: parent
70+ fill: parent
71+ topMargin: backgroundTopMargin
72+ }
66 source: root.required ? root.background : ""
73 source: root.required ? root.background : ""
67 fillMode: Image.PreserveAspectCrop
74 fillMode: Image.PreserveAspectCrop
68 }
75 }
@@ -88,7 +95,7 @@ Showable {
88 target: pinPadLoader.item
95 target: pinPadLoader.item
89
96
90 onEntered: {
97 onEntered: {
91− LightDM.Greeter.respond(passphrase);
98+ root.entered(passphrase);
92 }
99 }
93
100
94 onCancel: {
101 onCancel: {
@@ -146,19 +153,4 @@ Showable {
146 anchors.horizontalCenter: parent.horizontalCenter
153 anchors.horizontalCenter: parent.horizontalCenter
147 }
154 }
148 }
155 }
149−
150− Connections {
151− target: LightDM.Greeter
152−
153− onAuthenticationComplete: {
154− if (LightDM.Greeter.promptless) {
155− return;
156− }
157− if (LightDM.Greeter.authenticated) {
158− root.unlocked();
159− } else {
160− pinPadLoader.item.clear(true);
161− }
162− }
163− }
164}
156}
Greeter/PassphraseLockscreen.qml+1
@@ -82,6 +82,7 @@ Item {
82
82
83 WrongPasswordAnimation {
83 WrongPasswordAnimation {
84 id: wrongPasswordAnimation
84 id: wrongPasswordAnimation
85+ objectName: "wrongPasswordAnimation"
85 target: pinentryField
86 target: pinentryField
86 }
87 }
87}
88}
Greeter/PinLockscreen.qml+35−4
@@ -27,7 +27,7 @@ Column {
27 property alias placeholderText: pinentryField.placeholderText
27 property alias placeholderText: pinentryField.placeholderText
28 property int padWidth: units.gu(34)
28 property int padWidth: units.gu(34)
29 property int padHeight: units.gu(28)
29 property int padHeight: units.gu(28)
30− property int pinLength: 4
30+ property int pinLength: -1
31
31
32 signal entered(string passphrase)
32 signal entered(string passphrase)
33 signal cancel()
33 signal cancel()
@@ -65,6 +65,9 @@ Column {
65 Label {
65 Label {
66 id: pinentryFieldLabel
66 id: pinentryFieldLabel
67 anchors.centerIn: parent
67 anchors.centerIn: parent
68+ width: parent.width - (backspaceIcon.width + backspaceIcon.anchors.rightMargin) * 2
69+ elide: Text.ElideMiddle
70+ horizontalAlignment: Text.AlignHCenter
68 font.pixelSize: units.dp(44)
71 font.pixelSize: units.dp(44)
69 color: "#f3f3e7"
72 color: "#f3f3e7"
70 opacity: 0.6
73 opacity: 0.6
@@ -76,6 +79,26 @@ Column {
76 text: parent.placeholderText
79 text: parent.placeholderText
77 visible: pinentryFieldLabel.text.length == 0
80 visible: pinentryFieldLabel.text.length == 0
78 }
81 }
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+ }
79 }
102 }
80
103
81 UbuntuShape {
104 UbuntuShape {
@@ -154,7 +177,7 @@ Column {
154 objectName: "pinPadButtonBack"
177 objectName: "pinPadButtonBack"
155 width: root.padWidth / 3
178 width: root.padWidth / 3
156 height: root.padHeight / 4
179 height: root.padHeight / 4
157− iconName: "back"
180+ subText: "CANCEL"
158 onClicked: root.cancel();
181 onClicked: root.cancel();
159 }
182 }
160
183
@@ -171,8 +194,15 @@ Column {
171 objectName: "pinPadButtonErase"
194 objectName: "pinPadButtonErase"
172 width: root.padWidth / 3
195 width: root.padWidth / 3
173 height: root.padHeight / 4
196 height: root.padHeight / 4
174− iconName: "erase"
197+ iconName: root.pinLength == -1 ? "" : "erase"
198+ subText: root.pinLength == -1 ? "DONE" : ""
199+ onClicked: {
200+ if (root.pinLength !== -1) {
175− onClicked: pinentryField.text = pinentryField.text.substring(0, pinentryField.text.length-1)
201+ pinentryField.text = pinentryField.text.substring(0, pinentryField.text.length-1);
202+ } else {
203+ root.entered(pinentryField.text);
204+ }
205+ }
176 enabled: entryEnabled
206 enabled: entryEnabled
177 }
207 }
178 }
208 }
@@ -180,6 +210,7 @@ Column {
180
210
181 WrongPasswordAnimation {
211 WrongPasswordAnimation {
182 id: wrongPasswordAnimation
212 id: wrongPasswordAnimation
213+ objectName: "wrongPasswordAnimation"
183 target: pinentryField
214 target: pinentryField
184 }
215 }
185}
216}
Launcher/Launcher.qml+1−1
@@ -29,7 +29,7 @@ Item {
29 property int panelWidth: units.gu(8)
29 property int panelWidth: units.gu(8)
30 property int dragAreaWidth: units.gu(1)
30 property int dragAreaWidth: units.gu(1)
31 property int minimizeDistance: units.gu(26)
31 property int minimizeDistance: units.gu(26)
32− property real progress: dragArea.dragging && dragArea.touchX > panelWidth ?
32+ property real progress: dragArea.dragging && dragArea.touchX > panelWidth ?
33 (width * (dragArea.touchX-panelWidth) / (width - panelWidth)) : 0
33 (width * (dragArea.touchX-panelWidth) / (width - panelWidth)) : 0
34
34
35 readonly property bool shown: panel.x > -panel.width
35 readonly property bool shown: panel.x > -panel.width
Launcher/LauncherDelegate.qml+1
@@ -57,6 +57,7 @@ Item {
57 anchors.fill: parent
57 anchors.fill: parent
58 anchors.margins: units.gu(1)
58 anchors.margins: units.gu(1)
59 radius: "medium"
59 radius: "medium"
60+ borderSource: "none"
60
61
61 image: Image {
62 image: Image {
62 id: iconImage
63 id: iconImage
Launcher/LauncherPanel.qml+1−1
@@ -367,7 +367,7 @@ Item {
367 var yOffset = draggedIndex > 0 ? (mouseY + launcherListView.realContentY) % (draggedIndex * launcherListView.realItemHeight) : mouseY + launcherListView.realContentY
367 var yOffset = draggedIndex > 0 ? (mouseY + launcherListView.realContentY) % (draggedIndex * launcherListView.realItemHeight) : mouseY + launcherListView.realContentY
368
368
369 fakeDragItem.iconName = launcherListView.model.get(draggedIndex).icon
369 fakeDragItem.iconName = launcherListView.model.get(draggedIndex).icon
370− fakeDragItem.x = 0
370+ fakeDragItem.x = units.gu(0.5)
371 fakeDragItem.y = mouseY - yOffset + launcherListView.anchors.topMargin + launcherListView.topMargin
371 fakeDragItem.y = mouseY - yOffset + launcherListView.anchors.topMargin + launcherListView.topMargin
372 fakeDragItem.angle = selectedItem.angle * (root.inverted ? -1 : 1)
372 fakeDragItem.angle = selectedItem.angle * (root.inverted ? -1 : 1)
373 fakeDragItem.offset = selectedItem.offset * (root.inverted ? -1 : 1)
373 fakeDragItem.offset = selectedItem.offset * (root.inverted ? -1 : 1)
Notifications/Notification.qml+3−7
@@ -23,7 +23,7 @@ import Utils 0.1
23UbuntuShape {
23UbuntuShape {
24 id: notification
24 id: notification
25
25
26− property alias iconSource: avatarIcon.source
26+ property alias iconSource: icon.fileSource
27 property alias secondaryIconSource: secondaryIcon.source
27 property alias secondaryIconSource: secondaryIcon.source
28 property alias summary: summaryLabel.text
28 property alias summary: summaryLabel.text
29 property alias body: bodyLabel.text
29 property alias body: bodyLabel.text
@@ -102,18 +102,14 @@ UbuntuShape {
102 right: parent.right
102 right: parent.right
103 }
103 }
104
104
105− UbuntuShape {
105+ ShapedIcon {
106 id: icon
106 id: icon
107
107
108 objectName: "icon"
108 objectName: "icon"
109 width: units.gu(6)
109 width: units.gu(6)
110 height: units.gu(6)
110 height: units.gu(6)
111+ shaped: notification.hints["x-canonical-non-shaped-icon"] == "true" ? false : true
111 visible: iconSource !== undefined && iconSource != ""
112 visible: iconSource !== undefined && iconSource != ""
112− image: Image {
113− id: avatarIcon
114−
115− fillMode: Image.PreserveAspectCrop
116− }
117 }
113 }
118
114
119 Image {
115 Image {
Notifications/NotificationMenuItemFactory.qml+20−6
@@ -54,7 +54,8 @@ Loader {
54
54
55 Component.onCompleted: {
55 Component.onCompleted: {
56 menuModel.loadExtendedAttributes(menuIndex, {"x-echo-mode-password": "bool"});
56 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
58 }
59 }
59
60
60 Label {
61 Label {
@@ -65,11 +66,29 @@ Loader {
65 id: textfield
66 id: textfield
66
67
67 anchors.left: parent.left; anchors.right: parent.right
68 anchors.left: parent.left; anchors.right: parent.right
69+ echoMode: checkBox.checked ? TextInput.Normal : TextInput.Password
68 height: units.gu(5)
70 height: units.gu(5)
69 onTextChanged: {
71 onTextChanged: {
70 menuModel.changeState(menuIndex, text);
72 menuModel.changeState(menuIndex, text);
71 }
73 }
72 }
74 }
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+ }
73 }
92 }
74 }
93 }
75
94
@@ -78,11 +97,6 @@ Loader {
78 PinLockscreen {
97 PinLockscreen {
79 anchors.left: parent.left; anchors.right: parent.right
98 anchors.left: parent.left; anchors.right: parent.right
80
99
81− Component.onCompleted: {
82− menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-pin-length': 'int'});
83− pinLength = menuData.ext.xCanonicalPinLength;
84− }
85−
86 onEntered: {
100 onEntered: {
87 menuModel.changeState(menuIndex, passphrase);
101 menuModel.changeState(menuIndex, passphrase);
88 entryEnabled = false;
102 entryEnabled = false;
plugins/Unity/ratingoptionsmodel.cpp → Notifications/ShapedIcon.qmlrenamed+20−13
@@ -1,9 +1,6 @@
1/*
1/*
2 * Copyright (C) 2013 Canonical, Ltd.
2 * Copyright (C) 2013 Canonical, Ltd.
3 *
3 *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 3.
6 * the Free Software Foundation; version 3.
@@ -17,17 +14,27 @@
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
15 */
19
16
20−// self
17+import QtQuick 2.0
21−#include "ratingoptionsmodel.h"
18+import Ubuntu.Components 0.1
19+
20+Item {
21+ property string fileSource
22+ property bool shaped
23+
24+ UbuntuShape {
25+ objectName: "shapedIcon"
26+ anchors.fill: parent
27+ visible: shaped
28+ image: realImage
29+ }
22
30
23−// local
31+ Image {
24−#include "ratingfilteroption.h"
32+ id: realImage
25
33
26−RatingOptionsModel::RatingOptionsModel(bool showAllOption, QObject *parent) :
34+ objectName: "nonShapedIcon"
27− GenericOptionsModel(showAllOption, parent)
35+ anchors.fill: parent
28−{
36+ visible: !shaped
29− for (int i=1; i<=5; i++) {
37+ source: fileSource
30− auto opt = new RatingFilterOption(QString::number(i), i*0.2f, this);
38+ fillMode: Image.PreserveAspectCrop
31− addOption(opt);
32 }
39 }
33}
40}
Panel/Indicators.qml+37−10
@@ -21,7 +21,6 @@ import Unity.Indicators 0.1 as Indicators
21
21
22import "../Components"
22import "../Components"
23import "../Components/ListItems"
23import "../Components/ListItems"
24−import "../Components/Math.js" as MathLocal
25
24
26Showable {
25Showable {
27 id: indicators
26 id: indicators
@@ -38,6 +37,7 @@ Showable {
38 property bool partiallyOpened: height > panelHeight && !fullyOpened
37 property bool partiallyOpened: height > panelHeight && !fullyOpened
39 property real visualBottom: Math.max(y+height, y+indicatorRow.y+indicatorRow.height)
38 property real visualBottom: Math.max(y+height, y+indicatorRow.y+indicatorRow.height)
40 property bool contentEnabled: true
39 property bool contentEnabled: true
40+ property bool initalizeItem: true
41 readonly property alias content: menuContent
41 readonly property alias content: menuContent
42
42
43 // TODO: Perhaps we need a animation standard for showing/hiding? Each showable seems to
43 // TODO: Perhaps we need a animation standard for showing/hiding? Each showable seems to
@@ -64,14 +64,13 @@ Showable {
64 }
64 }
65
65
66 height: panelHeight
66 height: panelHeight
67+ onHeightChanged: updateRevealProgressState(indicators.height - panelHeight, true)
67
68
68− onHeightChanged: {
69+ function updateRevealProgressState(revealProgress, enableRelease) {
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
71 if (!showAnimation.running && !hideAnimation.running) {
70 if (!showAnimation.running && !hideAnimation.running) {
72− if (revealProgress == 0) {
71+ if (revealProgress === 0) {
73 indicators.state = "initial";
72 indicators.state = "initial";
74− } else if (revealProgress <= hintValue) {
73+ } else if (revealProgress > 0 && revealProgress <= hintValue) {
75 indicators.state = "hint";
74 indicators.state = "hint";
76 } else if (revealProgress > hintValue && revealProgress < lockThreshold) {
75 } else if (revealProgress > hintValue && revealProgress < lockThreshold) {
77 indicators.state = "reveal";
76 indicators.state = "reveal";
@@ -80,7 +79,7 @@ Showable {
80 }
79 }
81 }
80 }
82
81
83− if (revealProgress == 0) {
82+ if (enableRelease && revealProgress === 0) {
84 menuContent.releaseContent();
83 menuContent.releaseContent();
85 }
84 }
86 }
85 }
@@ -100,14 +99,14 @@ Showable {
100 Otherwise it contains the bar's location as a fraction of the distance between hintValue (is 0) and lockThreshold (is 1).
99 Otherwise it contains the bar's location as a fraction of the distance between hintValue (is 0) and lockThreshold (is 1).
101 */
100 */
102 var verticalProgress =
101 var verticalProgress =
103− MathLocal.clamp((indicators.height - handle.height - hintValue) /
102+ MathUtils.clamp((indicators.height - handle.height - hintValue) /
104 (lockThreshold - hintValue), 0, 1);
103 (lockThreshold - hintValue), 0, 1);
105
104
106 /*
105 /*
107 Vertical velocity check. Don't change the indicator if we're moving too quickly.
106 Vertical velocity check. Don't change the indicator if we're moving too quickly.
108 */
107 */
109 var verticalSpeed = Math.abs(yVelocityCalculator.calculate());
108 var verticalSpeed = Math.abs(yVelocityCalculator.calculate());
110− if (verticalSpeed >= 0.05 && indicatorRow.currentItem!=null) {
109+ if (verticalSpeed >= 0.05 && !initalizeItem) {
111 return;
110 return;
112 }
111 }
113
112
@@ -147,6 +146,7 @@ Showable {
147 } else if (!currentItem) {
146 } else if (!currentItem) {
148 indicatorRow.setDefaultItem();
147 indicatorRow.setDefaultItem();
149 }
148 }
149+ initalizeItem = indicatorRow.currentItem == null;
150 }
150 }
151
151
152 // eater
152 // eater
@@ -282,6 +282,33 @@ Showable {
282 enableIndexChangeSignal = oldActive;
282 enableIndexChangeSignal = oldActive;
283 }
283 }
284 }
284 }
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+ }
285 }
312 }
286
313
287 Connections {
314 Connections {
@@ -298,7 +325,7 @@ Showable {
298 onRunningChanged: {
325 onRunningChanged: {
299 if (hideAnimation.running) {
326 if (hideAnimation.running) {
300 indicators.state = "initial";
327 indicators.state = "initial";
301− indicatorRow.currentItem = null;
328+ initalizeItem = true;
302 }
329 }
303 }
330 }
304 }
331 }
Panel/Indicators/DefaultIndicatorWidget.qml+32−10
@@ -24,7 +24,7 @@ import Unity.Indicators 0.1 as Indicators
24Indicators.IndicatorWidget {
24Indicators.IndicatorWidget {
25 id: indicatorWidget
25 id: indicatorWidget
26
26
27− width: itemRow.width + units.gu(0.5)
27+ width: itemRow.width
28
28
29 property alias leftLabel: itemLeftLabel.text
29 property alias leftLabel: itemLeftLabel.text
30 property alias rightLabel: itemRightLabel.text
30 property alias rightLabel: itemRightLabel.text
@@ -32,16 +32,17 @@ Indicators.IndicatorWidget {
32
32
33 Row {
33 Row {
34 id: itemRow
34 id: itemRow
35+ width: childrenRect.width
35 objectName: "itemRow"
36 objectName: "itemRow"
36 anchors {
37 anchors {
37 top: parent.top
38 top: parent.top
38 bottom: parent.bottom
39 bottom: parent.bottom
39 horizontalCenter: parent.horizontalCenter
40 horizontalCenter: parent.horizontalCenter
40 }
41 }
41− spacing: units.gu(0.5)
42
42
43 Label {
43 Label {
44 id: itemLeftLabel
44 id: itemLeftLabel
45+ width: guRoundUp(implicitWidth)
45 objectName: "leftLabel"
46 objectName: "leftLabel"
46 color: Theme.palette.selected.backgroundText
47 color: Theme.palette.selected.backgroundText
47 opacity: 0.8
48 opacity: 0.8
@@ -57,25 +58,35 @@ Indicators.IndicatorWidget {
57 top: parent.top
58 top: parent.top
58 bottom: parent.bottom
59 bottom: parent.bottom
59 }
60 }
60− spacing: units.gu(0.5)
61
61
62 Repeater {
62 Repeater {
63 model: indicatorWidget.icons
63 model: indicatorWidget.icons
64
64
65− Image {
65+ Item {
66− id: itemImage
66+ width: guRoundUp(itemImage.width)
67− objectName: "itemImage"
68− visible: source != ""
69− source: modelData
70 height: indicatorWidget.iconSize
67 height: indicatorWidget.iconSize
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 {
71− width: indicatorWidget.iconSize
79+ width: indicatorWidget.iconSize
72− anchors.verticalCenter: parent.verticalCenter
80+ height: indicatorWidget.iconSize
81+ }
82+ }
73 }
83 }
74 }
84 }
75 }
85 }
76
86
77 Label {
87 Label {
78 id: itemRightLabel
88 id: itemRightLabel
89+ width: guRoundUp(implicitWidth)
79 objectName: "rightLabel"
90 objectName: "rightLabel"
80 color: Theme.palette.selected.backgroundText
91 color: Theme.palette.selected.backgroundText
81 opacity: 0.8
92 opacity: 0.8
@@ -86,6 +97,17 @@ Indicators.IndicatorWidget {
86 }
97 }
87 }
98 }
88
99
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+
89 onRootActionStateChanged: {
111 onRootActionStateChanged: {
90 if (rootActionState == undefined) {
112 if (rootActionState == undefined) {
91 leftLabel = "";
113 leftLabel = "";
Panel/Indicators/client/IndicatorsTree.qml+2−3
@@ -29,10 +29,9 @@ Page {
29
29
30 property string busName: unityModel.busName
30 property string busName: unityModel.busName
31 property string actionsObjectPath
31 property string actionsObjectPath
32− property var menuObjectPaths: undefined
32+ property string menuObjectPath
33− readonly property string device: "phone"
34
33
35− property string deviceMenuObjectPath: menuObjectPaths.hasOwnProperty(device) ? menuObjectPaths[device] : ""
34+ property string deviceMenuObjectPath: menuObjectPath
36
35
37 function start() {
36 function start() {
38 }
37 }
Shell.qml+21−6
@@ -30,7 +30,6 @@ import "Launcher"
30import "Panel"
30import "Panel"
31import "Hud"
31import "Hud"
32import "Components"
32import "Components"
33−import "Components/Math.js" as MathLocal
34import "Bottombar"
33import "Bottombar"
35import "SideStage"
34import "SideStage"
36import "Notifications"
35import "Notifications"
@@ -62,8 +61,6 @@ FocusScope {
62 }
61 }
63 }
62 }
64
63
65− property ListModel searchHistory: SearchHistoryModel {}
66−
67 property var applicationManager: ApplicationManagerWrapper {}
64 property var applicationManager: ApplicationManagerWrapper {}
68
65
69 Binding {
66 Binding {
@@ -237,7 +234,7 @@ FocusScope {
237 Behavior on x {SmoothedAnimation{velocity: 600}}
234 Behavior on x {SmoothedAnimation{velocity: 600}}
238
235
239 property real showProgress:
236 property real showProgress:
240− MathLocal.clamp(1 - (x + stages.x) / shell.width, 0, 1)
237+ MathUtils.clamp(1 - (x + stages.x) / shell.width, 0, 1)
241
238
242 Showable {
239 Showable {
243 id: stages
240 id: stages
@@ -402,6 +399,10 @@ FocusScope {
402
399
403 Lockscreen {
400 Lockscreen {
404 id: lockscreen
401 id: lockscreen
402+ objectName: "lockscreen"
403+
404+ readonly property int backgroundTopMargin: -panel.panelHeight
405+
405 hides: [launcher, panel.indicators, hud]
406 hides: [launcher, panel.indicators, hud]
406 shown: false
407 shown: false
407 enabled: true
408 enabled: true
@@ -413,7 +414,7 @@ FocusScope {
413 height: parent.height - panel.panelHeight
414 height: parent.height - panel.panelHeight
414 background: shell.background
415 background: shell.background
415
416
416− onUnlocked: lockscreen.hide()
417+ onEntered: LightDM.Greeter.respond(passphrase);
417 onCancel: greeter.show()
418 onCancel: greeter.show()
418
419
419 Component.onCompleted: {
420 Component.onCompleted: {
@@ -439,6 +440,17 @@ FocusScope {
439 lockscreen.show();
440 lockscreen.show();
440 }
441 }
441 }
442 }
443+
444+ onAuthenticationComplete: {
445+ if (LightDM.Greeter.promptless) {
446+ return;
447+ }
448+ if (LightDM.Greeter.authenticated) {
449+ lockscreen.hide();
450+ } else {
451+ lockscreen.clear(true);
452+ }
453+ }
442 }
454 }
443
455
444 Greeter {
456 Greeter {
@@ -647,19 +659,22 @@ FocusScope {
647 Launcher {
659 Launcher {
648 id: launcher
660 id: launcher
649
661
662+ readonly property bool dashSwipe: progress > 0
663+
650 anchors.top: parent.top
664 anchors.top: parent.top
651 anchors.bottom: parent.bottom
665 anchors.bottom: parent.bottom
652 width: parent.width
666 width: parent.width
653 dragAreaWidth: shell.edgeSize
667 dragAreaWidth: shell.edgeSize
654 available: (!greeter.shown || greeter.narrowMode) && edgeDemo.launcherEnabled
668 available: (!greeter.shown || greeter.narrowMode) && edgeDemo.launcherEnabled
669+
655 onDashItemSelected: showHome()
670 onDashItemSelected: showHome()
656 onDash: {
671 onDash: {
657 if (stages.shown) {
672 if (stages.shown) {
658− dash.setCurrentScope("applications.scope", true /* animate */, true /* reset */)
659 stages.hide();
673 stages.hide();
660 launcher.hide();
674 launcher.hide();
661 }
675 }
662 }
676 }
677+ onDashSwipeChanged: if (dashSwipe && stages.shown) dash.setCurrentScope("applications.scope", false, true)
663 onLauncherApplicationSelected:{
678 onLauncherApplicationSelected:{
664 greeter.hide()
679 greeter.hide()
665 shell.activateApplication(appId)
680 shell.activateApplication(appId)
build+1
@@ -50,6 +50,7 @@ install_dependencies() {
50 ubuntu-mobile-icons \
50 ubuntu-mobile-icons \
51 unity-scope-home \
51 unity-scope-home \
52 unity-lens-applications \
52 unity-lens-applications \
53+ unity-plugin-scopes \
53 || exit 5
54 || exit 5
54}
55}
55
56
cmake/modules/Plugins.cmake+3−3
@@ -28,7 +28,7 @@ macro(export_qmlfiles PLUGIN PLUGIN_SUBPATH)
28
28
29 # install the qmlfiles file.
29 # install the qmlfiles file.
30 install(FILES ${QMLFILES}
30 install(FILES ${QMLFILES}
31− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/${PLUGIN_SUBPATH}
31+ DESTINATION ${SHELL_INSTALL_QML}/${PLUGIN_SUBPATH}
32 )
32 )
33endmacro(export_qmlfiles)
33endmacro(export_qmlfiles)
34
34
@@ -56,12 +56,12 @@ macro(export_qmlplugin PLUGIN VERSION PLUGIN_SUBPATH)
56
56
57 # install the qmltypes file.
57 # install the qmltypes file.
58 install(FILES ${CMAKE_BINARY_DIR}/plugins/${PLUGIN_SUBPATH}/plugin.qmltypes
58 install(FILES ${CMAKE_BINARY_DIR}/plugins/${PLUGIN_SUBPATH}/plugin.qmltypes
59− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/${PLUGIN_SUBPATH}
59+ DESTINATION ${SHELL_INSTALL_QML}/${PLUGIN_SUBPATH}
60 )
60 )
61 endif()
61 endif()
62
62
63 # install the additional targets
63 # install the additional targets
64 install(TARGETS ${qmlplugin_TARGETS}
64 install(TARGETS ${qmlplugin_TARGETS}
65− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/${PLUGIN_SUBPATH}
65+ DESTINATION ${SHELL_INSTALL_QML}/${PLUGIN_SUBPATH}
66 )
66 )
67endmacro(export_qmlplugin)
67endmacro(export_qmlplugin)
cmake/modules/autopilot.cmake+1−1
@@ -2,7 +2,7 @@ add_custom_target(autopilot)
2
2
3function(declare_autopilot_test TEST_NAME TEST_SUITE WORKING_DIR)
3function(declare_autopilot_test TEST_NAME TEST_SUITE WORKING_DIR)
4 add_custom_target(autopilot-${TEST_NAME}
4 add_custom_target(autopilot-${TEST_NAME}
5− COMMAND LANG=C UBUNTU_ICON_THEME=ubuntu-mobile QML2_IMPORT_PATH=${SHELL_PRIVATE_LIBDIR}/qml/mocks autopilot run ${TEST_SUITE}
5+ COMMAND LANG=C UBUNTU_ICON_THEME=ubuntu-mobile QML2_IMPORT_PATH=${SHELL_INSTALL_QML}/mocks autopilot run ${TEST_SUITE}
6 WORKING_DIRECTORY ${WORKING_DIR}
6 WORKING_DIRECTORY ${WORKING_DIR}
7 DEPENDS install
7 DEPENDS install
8 )
8 )
data/unity8.conf+20
@@ -6,4 +6,24 @@ stop on desktop-end
6
6
7respawn
7respawn
8
8
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+
9exec ${BINARY:-unity8} $ARGS
29exec ${BINARY:-unity8} $ARGS
debian/changelog+72
@@ -1,3 +1,75 @@
1+unity8 (7.84-0ubuntu1) UNRELEASED; urgency=low
2+
3+ * Depend on the separate scopes plugin
4+
5+ -- Michal Hruby <michal.hruby@canonical.com> Wed, 13 Nov 2013 12:43:39 +0000
6+
7+unity8 (7.83+14.04.20131106-0ubuntu1) trusty; urgency=low
8+
9+ [ Andrea Cimitan ]
10+ * Place ShaderEffectSource of UbuntuShapeForItem under the Shape Item.
11+ (LP: #1239317)
12+
13+ [ Omer Akram ]
14+ * test: make sure the search indicator hides when an app has focus.
15+
16+ [ Nick Dedekind ]
17+ * Fixed indicator slider menu item alignment to label field and icon.
18+ (LP: #1240756)
19+
20+ [ chris.gagnon ]
21+ * Update to autopilot 1.4.
22+
23+ [ Ubuntu daily release ]
24+ * Automatic snapshot from revision 500
25+
26+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 06 Nov 2013 03:37:02 +0000
27+
28+unity8 (7.83+14.04.20131105.1-0ubuntu1) trusty; urgency=low
29+
30+ [ Michał Sawicz ]
31+ * Implement switching between previews by swiping. (LP: #1220651,
32+ #1088572)
33+
34+ [ Nick Dedekind ]
35+ * Faster loading of indicator menus. (LP: #1226650)
36+
37+ [ Albert Astals ]
38+ * Make sure we have ssh started when we need it .
39+ * Fix a few warnings in DashContent.qml on shutdown
40+ Dash/DashContent.qml:119: TypeError: Cannot read property
41+ 'previewShown' of null Dash/DashContent.qml:120: TypeError: Cannot
42+ read property 'moving' of null .
43+ * Don't use deprecated Panel methods.
44+
45+ [ Christopher Lee ]
46+ * Adds an easy to consume function that attempts to unlock the unity
47+ greeter. (LP: #1240261)
48+
49+ [ Lars Uebernickel ]
50+ * Indicators: add TimeFormatter and use it in the messaging menu This
51+ component can be used to turn a timestamp and a format string into a
52+ string with the corresponding time and format. The string will
53+ change whenever the timezone changes. (LP: #1236413)
54+
55+ [ Andrea Cimitan ]
56+ * Allow drag over bounds, but not overshoot. (LP: #1204300)
57+ * Threshold to activate the left edge swipe to reveal dash is now 26
58+ GU. (LP: #1236286)
59+
60+ [ Michael Zanetti ]
61+ * replace the launcher quicklist's Popover with an own quicklist
62+ implementation The Popover probably won't ever support what the
63+ launcher needs.
64+ * Implement switching between previews by swiping. (LP: #1220651,
65+ #1088572)
66+ * don't trigger the greeter teasing during a movement of the greeter.
67+
68+ [ Ubuntu daily release ]
69+ * Automatic snapshot from revision 495
70+
71+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 05 Nov 2013 12:22:04 +0000
72+
1unity8 (7.83+14.04.20131031-0ubuntu1) trusty; urgency=low
73unity8 (7.83+14.04.20131031-0ubuntu1) trusty; urgency=low
2
74
3 [ Michał Sawicz ]
75 [ Michał Sawicz ]
debian/control+4−5
@@ -17,10 +17,7 @@ Build-Depends: cmake,
17 libpulse-dev,
17 libpulse-dev,
18 libqmenumodel-dev (>= 0.2.7),
18 libqmenumodel-dev (>= 0.2.7),
19 libqt5v8-5-private-dev,
19 libqt5v8-5-private-dev,
20− libsigc++-2.0-dev,
21− libunity-api-dev (>= 7.80.3),
20+ libunity-api-dev (>= 7.80.4),
22− libunity-core-6.0-dev (>= 7.1.1),
23− libunity-dev (>= 7.0.12),
24 libunity-mir-dev,
21 libunity-mir-dev,
25 libunity-scopes-json-def-phone,
22 libunity-scopes-json-def-phone,
26 libupstart-dev,
23 libupstart-dev,
@@ -78,6 +75,8 @@ Depends: gsettings-desktop-schemas,
78 unity8-fake-env | qtubuntu-shell,
75 unity8-fake-env | qtubuntu-shell,
79 unity8-private (= ${binary:Version}),
76 unity8-private (= ${binary:Version}),
80 unity8-private | unity-launcher-impl,
77 unity8-private | unity-launcher-impl,
78+ unity-plugin-scopes | unity-scopes-impl,
79+ unity-scopes-impl-0,
81# for setcap:
80# for setcap:
82 libcap2-bin,
81 libcap2-bin,
83 ${misc:Depends},
82 ${misc:Depends},
@@ -91,7 +90,7 @@ Description: Unity 8 shell
91Package: unity8-autopilot
90Package: unity8-autopilot
92Architecture: all
91Architecture: all
93Depends: gir1.2-glib-2.0,
92Depends: gir1.2-glib-2.0,
94− libautopilot-qt,
93+ libautopilot-qt (>= 1.4),
95 libqt5test5,
94 libqt5test5,
96 libqt5widgets5,
95 libqt5widgets5,
97 python-evdev,
96 python-evdev,
paths.h.in+4−2
@@ -58,9 +58,11 @@ inline QStringList overrideImportPaths() {
58inline QStringList fallbackImportPaths() {
58inline QStringList fallbackImportPaths() {
59 QStringList paths;
59 QStringList paths;
60 if (isRunningInstalled()) {
60 if (isRunningInstalled()) {
61− paths << QString("@CMAKE_INSTALL_PREFIX@/@SHELL_PRIVATE_LIBDIR@/qml");
61+ paths << QString("@CMAKE_INSTALL_PREFIX@/@SHELL_INSTALL_QML@");
62+ paths << QString("@SHELL_PLUGINDIR@");
62− paths << QString("@CMAKE_INSTALL_PREFIX@/@SHELL_PRIVATE_LIBDIR@/qml/mocks");
63+ paths << QString("@CMAKE_INSTALL_PREFIX@/@SHELL_INSTALL_QML@/mocks");
63 } else {
64 } else {
65+ paths << QString("@SHELL_PLUGINDIR@");
64 paths << QString("@CMAKE_BINARY_DIR@/tests/mocks");
66 paths << QString("@CMAKE_BINARY_DIR@/tests/mocks");
65 }
67 }
66 return paths;
68 return paths;
plugins/AccountsService/plugin.cpp+1−1
@@ -20,7 +20,7 @@
20#include "AccountsService.h"
20#include "AccountsService.h"
21
21
22#include <QDBusMetaType>
22#include <QDBusMetaType>
23−#include <QtQml>
23+#include <QtQml/qqml.h>
24
24
25static QObject *service_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
25static QObject *service_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
26{
26{
plugins/ListViewWithPageHeader/listviewwithpageheader.cpp+32−6
@@ -155,6 +155,7 @@ ListViewWithPageHeader::ListViewWithPageHeader()
155 , m_topSectionItem(nullptr)
155 , m_topSectionItem(nullptr)
156 , m_forceNoClip(false)
156 , m_forceNoClip(false)
157 , m_inLayout(false)
157 , m_inLayout(false)
158+ , m_inContentHeightKeepHeaderShown(false)
158{
159{
159 m_clipItem = new QQuickItem(contentItem());
160 m_clipItem = new QQuickItem(contentItem());
160// m_clipItem = new QQuickRectangle(contentItem());
161// m_clipItem = new QQuickRectangle(contentItem());
@@ -286,10 +287,12 @@ void ListViewWithPageHeader::setSectionDelegate(QQmlComponent *delegate)
286 m_topSectionItem = getSectionItem(QString());
287 m_topSectionItem = getSectionItem(QString());
287 m_topSectionItem->setZ(3);
288 m_topSectionItem->setZ(3);
288 QQuickItemPrivate::get(m_topSectionItem)->setCulled(true);
289 QQuickItemPrivate::get(m_topSectionItem)->setCulled(true);
290+ connect(m_topSectionItem, SIGNAL(heightChanged()), SIGNAL(stickyHeaderHeightChanged()));
289
291
290 // TODO create sections for existing items
292 // TODO create sections for existing items
291
293
292 Q_EMIT sectionDelegateChanged();
294 Q_EMIT sectionDelegateChanged();
295+ Q_EMIT stickyHeaderHeightChanged();
293 }
296 }
294}
297}
295
298
@@ -325,6 +328,11 @@ void ListViewWithPageHeader::setForceNoClip(bool noClip)
325 }
328 }
326}
329}
327
330
331+int ListViewWithPageHeader::stickyHeaderHeight() const
332+{
333+ return m_topSectionItem ? m_topSectionItem->height() : 0;
334+}
335+
328void ListViewWithPageHeader::positionAtBeginning()
336void ListViewWithPageHeader::positionAtBeginning()
329{
337{
330 if (m_delegateModel->count() <= 0)
338 if (m_delegateModel->count() <= 0)
@@ -471,12 +479,18 @@ void ListViewWithPageHeader::componentComplete()
471
479
472void ListViewWithPageHeader::viewportMoved(Qt::Orientations orient)
480void ListViewWithPageHeader::viewportMoved(Qt::Orientations orient)
473{
481{
482+ // Check we are not being taken down and don't paint anything
483+ // TODO Check if we still need this in 5.2
484+ // For reproduction just inifnite loop testDash or testDashContent
485+ if (!QQmlEngine::contextForObject(this)->parentContext())
486+ return;
487+
474 QQuickFlickable::viewportMoved(orient);
488 QQuickFlickable::viewportMoved(orient);
475// qDebug() << "ListViewWithPageHeader::viewportMoved" << contentY();
489// qDebug() << "ListViewWithPageHeader::viewportMoved" << contentY();
476 qreal diff = m_previousContentY - contentY();
490 qreal diff = m_previousContentY - contentY();
477 const bool showHeaderAnimationRunning = m_contentYAnimation->isRunning() && contentYAnimationType == ContentYAnimationShowHeader;
491 const bool showHeaderAnimationRunning = m_contentYAnimation->isRunning() && contentYAnimationType == ContentYAnimationShowHeader;
478 if (m_headerItem) {
492 if (m_headerItem) {
479− auto oldHeaderItemShownHeight = m_headerItemShownHeight;
493+ const auto oldHeaderItemShownHeight = m_headerItemShownHeight;
480 if (contentY() < -m_minYExtent) {
494 if (contentY() < -m_minYExtent) {
481 // Stick the header item to the top when dragging down
495 // Stick the header item to the top when dragging down
482 m_headerItem->setY(contentY());
496 m_headerItem->setY(contentY());
@@ -491,10 +505,10 @@ void ListViewWithPageHeader::viewportMoved(Qt::Orientations orient)
491 const bool notShownByItsOwn = contentY() + diff >= m_headerItem->y() + m_headerItem->height();
505 const bool notShownByItsOwn = contentY() + diff >= m_headerItem->y() + m_headerItem->height();
492 const bool maximizeVisibleAreaRunning = m_contentYAnimation->isRunning() && contentYAnimationType == ContentYAnimationMaximizeVisibleArea;
506 const bool maximizeVisibleAreaRunning = m_contentYAnimation->isRunning() && contentYAnimationType == ContentYAnimationMaximizeVisibleArea;
493
507
494− if (!scrolledUp && contentY() == -m_minYExtent) {
508+ if (!scrolledUp && (contentY() == -m_minYExtent || (m_headerItemShownHeight == 0 && m_previousContentY == m_headerItem->y()))) {
495 m_headerItemShownHeight = 0;
509 m_headerItemShownHeight = 0;
496− m_headerItem->setY(contentY());
510+ m_headerItem->setY(-m_minYExtent);
497− } else if ((scrolledUp && notRebounding && notShownByItsOwn && !maximizeVisibleAreaRunning) || (m_headerItemShownHeight > 0)) {
511+ } else if ((scrolledUp && notRebounding && notShownByItsOwn && !maximizeVisibleAreaRunning) || (m_headerItemShownHeight > 0) || m_inContentHeightKeepHeaderShown) {
498 if (maximizeVisibleAreaRunning && diff > 0) // If we are maximizing and the header was shown, make sure we hide it
512 if (maximizeVisibleAreaRunning && diff > 0) // If we are maximizing and the header was shown, make sure we hide it
499 m_headerItemShownHeight -= diff;
513 m_headerItemShownHeight -= diff;
500 else
514 else
@@ -847,6 +861,11 @@ void ListViewWithPageHeader::itemCreated(int modelIndex, QObject *object)
847 }
861 }
848#endif
862#endif
849// qDebug() << "ListViewWithPageHeader::itemCreated" << modelIndex << item;
863// qDebug() << "ListViewWithPageHeader::itemCreated" << modelIndex << item;
864+ // Check we are not being taken down and don't paint anything
865+ // TODO Check if we still need this in 5.2
866+ // For reproduction just inifnite loop testDash or testDashContent
867+ if (!QQmlEngine::contextForObject(this)->parentContext())
868+ return;
850
869
851 item->setParentItem(m_clipItem);
870 item->setParentItem(m_clipItem);
852 QQmlContext *context = QQmlEngine::contextForObject(item)->parentContext();
871 QQmlContext *context = QQmlEngine::contextForObject(item)->parentContext();
@@ -980,7 +999,6 @@ void ListViewWithPageHeader::onModelUpdated(const QQmlChangeSet &changeSet, bool
980 if (growUp) {
999 if (growUp) {
981 ListItem *firstItem = m_visibleItems.first();
1000 ListItem *firstItem = m_visibleItems.first();
982 firstItem->setY(firstItem->y() - item->height());
1001 firstItem->setY(firstItem->y() - item->height());
983− adjustMinYExtent();
984 }
1002 }
985 // Adding an item may break a "same section" chain, so check
1003 // Adding an item may break a "same section" chain, so check
986 // if we need adding a new section item
1004 // if we need adding a new section item
@@ -991,7 +1009,6 @@ void ListViewWithPageHeader::onModelUpdated(const QQmlChangeSet &changeSet, bool
991 if (growUp && nextItem->m_sectionItem) {
1009 if (growUp && nextItem->m_sectionItem) {
992 ListItem *firstItem = m_visibleItems.first();
1010 ListItem *firstItem = m_visibleItems.first();
993 firstItem->setY(firstItem->y() - nextItem->m_sectionItem->height());
1011 firstItem->setY(firstItem->y() - nextItem->m_sectionItem->height());
994− adjustMinYExtent();
995 }
1012 }
996 }
1013 }
997 }
1014 }
@@ -1000,6 +1017,7 @@ void ListViewWithPageHeader::onModelUpdated(const QQmlChangeSet &changeSet, bool
1000 ListItem *firstItem = m_visibleItems.first();
1017 ListItem *firstItem = m_visibleItems.first();
1001 firstItem->setY(oldFirstValidIndexPos);
1018 firstItem->setY(oldFirstValidIndexPos);
1002 }
1019 }
1020+ adjustMinYExtent();
1003 } else if (insert.index <= m_firstVisibleIndex) {
1021 } else if (insert.index <= m_firstVisibleIndex) {
1004 m_firstVisibleIndex += insert.count;
1022 m_firstVisibleIndex += insert.count;
1005 }
1023 }
@@ -1228,6 +1246,12 @@ void ListViewWithPageHeader::layout()
1228
1246
1229void ListViewWithPageHeader::updatePolish()
1247void ListViewWithPageHeader::updatePolish()
1230{
1248{
1249+ // Check we are not being taken down and don't paint anything
1250+ // TODO Check if we still need this in 5.2
1251+ // For reproduction just inifnite loop testDash or testDashContent
1252+ if (!QQmlEngine::contextForObject(this)->parentContext())
1253+ return;
1254+
1231 Q_FOREACH(ListItem *item, m_itemsToRelease)
1255 Q_FOREACH(ListItem *item, m_itemsToRelease)
1232 reallyReleaseItem(item);
1256 reallyReleaseItem(item);
1233 m_itemsToRelease.clear();
1257 m_itemsToRelease.clear();
@@ -1267,7 +1291,9 @@ void ListViewWithPageHeader::updatePolish()
1267
1291
1268 m_contentHeightDirty = false;
1292 m_contentHeightDirty = false;
1269 adjustMinYExtent();
1293 adjustMinYExtent();
1294+ m_inContentHeightKeepHeaderShown = m_headerItem && m_headerItem->y() == contentY();
1270 setContentHeight(contentHeight);
1295 setContentHeight(contentHeight);
1296+ m_inContentHeightKeepHeaderShown = false;
1271 }
1297 }
1272}
1298}
1273
1299
plugins/ListViewWithPageHeader/listviewwithpageheader.h+5
@@ -60,6 +60,7 @@ class ListViewWithPageHeader : public QQuickFlickable, public QQuickItemChangeLi
60 Q_PROPERTY(QQmlComponent *sectionDelegate READ sectionDelegate WRITE setSectionDelegate NOTIFY sectionDelegateChanged)
60 Q_PROPERTY(QQmlComponent *sectionDelegate READ sectionDelegate WRITE setSectionDelegate NOTIFY sectionDelegateChanged)
61 Q_PROPERTY(QString sectionProperty READ sectionProperty WRITE setSectionProperty NOTIFY sectionPropertyChanged)
61 Q_PROPERTY(QString sectionProperty READ sectionProperty WRITE setSectionProperty NOTIFY sectionPropertyChanged)
62 Q_PROPERTY(bool forceNoClip READ forceNoClip WRITE setForceNoClip NOTIFY forceNoClipChanged)
62 Q_PROPERTY(bool forceNoClip READ forceNoClip WRITE setForceNoClip NOTIFY forceNoClipChanged)
63+ Q_PROPERTY(int stickyHeaderHeight READ stickyHeaderHeight NOTIFY stickyHeaderHeightChanged)
63
64
64 friend class ListViewWithPageHeaderTest;
65 friend class ListViewWithPageHeaderTest;
65 friend class ListViewWithPageHeaderTestSection;
66 friend class ListViewWithPageHeaderTestSection;
@@ -87,6 +88,8 @@ public:
87 bool forceNoClip() const;
88 bool forceNoClip() const;
88 void setForceNoClip(bool noClip);
89 void setForceNoClip(bool noClip);
89
90
91+ int stickyHeaderHeight() const;
92+
90 Q_INVOKABLE void positionAtBeginning();
93 Q_INVOKABLE void positionAtBeginning();
91 Q_INVOKABLE void showHeader();
94 Q_INVOKABLE void showHeader();
92 Q_INVOKABLE QQuickItem *item(int modelIndex) const;
95 Q_INVOKABLE QQuickItem *item(int modelIndex) const;
@@ -104,6 +107,7 @@ Q_SIGNALS:
104 void sectionDelegateChanged();
107 void sectionDelegateChanged();
105 void sectionPropertyChanged();
108 void sectionPropertyChanged();
106 void forceNoClipChanged();
109 void forceNoClipChanged();
110+ void stickyHeaderHeightChanged();
107
111
108protected:
112protected:
109 void componentComplete();
113 void componentComplete();
@@ -202,6 +206,7 @@ private:
202
206
203 bool m_forceNoClip;
207 bool m_forceNoClip;
204 bool m_inLayout;
208 bool m_inLayout;
209+ bool m_inContentHeightKeepHeaderShown;
205
210
206 // Qt 5.0 doesn't like releasing the items just after itemCreated
211 // Qt 5.0 doesn't like releasing the items just after itemCreated
207 // so we delay the releasing until the next updatePolish
212 // so we delay the releasing until the next updatePolish
plugins/SessionBroadcast/plugin.cpp+1−1
@@ -19,7 +19,7 @@
19#include "plugin.h"
19#include "plugin.h"
20#include "SessionBroadcast.h"
20#include "SessionBroadcast.h"
21
21
22−#include <QtQml>
22+#include <QtQml/qqml.h>
23
23
24static QObject *broadcast_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
24static QObject *broadcast_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
25{
25{
plugins/Ubuntu/Gestures/AxisVelocityCalculator.cpp+9−18
@@ -21,25 +21,19 @@
21#include "AxisVelocityCalculator.h"
21#include "AxisVelocityCalculator.h"
22#include <QtCore/QElapsedTimer>
22#include <QtCore/QElapsedTimer>
23
23
24−class RealTimeSource : public UbuntuGestures::TimeSource {
25−public:
26− RealTimeSource()
27− : UbuntuGestures::TimeSource() {
24+using namespace UbuntuGestures;
28− m_timer.start();
29− }
30− virtual qint64 msecsSinceReference() {
31− return m_timer.elapsed();
32− }
33−private:
34− QElapsedTimer m_timer;
35−};
36
25
37AxisVelocityCalculator::AxisVelocityCalculator(QObject *parent)
26AxisVelocityCalculator::AxisVelocityCalculator(QObject *parent)
27+ : AxisVelocityCalculator(SharedTimeSource(new RealTimeSource), parent)
28+{
29+}
30+
31+AxisVelocityCalculator::AxisVelocityCalculator(const SharedTimeSource &timeSource,
32+ QObject *parent)
38 : QObject(parent)
33 : QObject(parent)
39− , m_timeSource(new RealTimeSource)
34+ , m_timeSource(timeSource)
40 , m_trackedPosition(0.0)
35 , m_trackedPosition(0.0)
41{
36{
42− m_timeSource->setParent(this);
43 reset();
37 reset();
44}
38}
45
39
@@ -142,11 +136,8 @@ int AxisVelocityCalculator::numSamples() const
142 }
136 }
143}
137}
144
138
145−void AxisVelocityCalculator::setTimeSource(UbuntuGestures::TimeSource *timeSource)
139+void AxisVelocityCalculator::setTimeSource(const SharedTimeSource &timeSource)
146{
140{
147− if (m_timeSource && m_timeSource->parent() == this)
148− delete m_timeSource;
149−
150 m_timeSource = timeSource;
141 m_timeSource = timeSource;
151
142
152 if (numSamples() > 0) {
143 if (numSamples() > 0) {
plugins/Ubuntu/Gestures/AxisVelocityCalculator.h+9−16
@@ -24,19 +24,7 @@
24#include "UbuntuGesturesGlobal.h"
24#include "UbuntuGesturesGlobal.h"
25#include <stdint.h>
25#include <stdint.h>
26#include <QtCore/QObject>
26#include <QtCore/QObject>
27−
27+#include "TimeSource.h"
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−}
40
28
41/*
29/*
42 Estimates the current velocity of a finger based on recent movement along an axis
30 Estimates the current velocity of a finger based on recent movement along an axis
@@ -73,10 +61,15 @@ class UBUNTUGESTURES_EXPORT AxisVelocityCalculator : public QObject
73public:
61public:
74
62
75 /*
63 /*
76− Regular constructor
64+ Regular, simple, constructor
77 */
65 */
78 AxisVelocityCalculator(QObject *parent = 0);
66 AxisVelocityCalculator(QObject *parent = 0);
79
67
68+ /*
69+ Constructor that takes a TimeSource
70+ */
71+ AxisVelocityCalculator(const UbuntuGestures::SharedTimeSource &timeSource, QObject *parent = 0);
72+
80 virtual ~AxisVelocityCalculator();
73 virtual ~AxisVelocityCalculator();
81
74
82 qreal trackedPosition() const;
75 qreal trackedPosition() const;
@@ -97,7 +90,7 @@ public:
97 /*
90 /*
98 Replaces the TimeSource with the given one. Useful for testing purposes.
91 Replaces the TimeSource with the given one. Useful for testing purposes.
99 */
92 */
100− void setTimeSource(UbuntuGestures::TimeSource *timeSource);
93+ void setTimeSource(const UbuntuGestures::SharedTimeSource &timeSource);
101
94
102 /*
95 /*
103 The minimum amount of samples needed for a velocity calculation.
96 The minimum amount of samples needed for a velocity calculation.
@@ -145,7 +138,7 @@ private:
145 int m_samplesRead; /* index of the oldest sample available. -1 if buffer is empty */
138 int m_samplesRead; /* index of the oldest sample available. -1 if buffer is empty */
146 int m_samplesWrite; /* index where the next sample will be written */
139 int m_samplesWrite; /* index where the next sample will be written */
147
140
148− UbuntuGestures::TimeSource *m_timeSource;
141+ UbuntuGestures::SharedTimeSource m_timeSource;
149
142
150 qreal m_trackedPosition;
143 qreal m_trackedPosition;
151};
144};
plugins/Ubuntu/Gestures/CMakeLists.txt+1
@@ -6,6 +6,7 @@ set(UbuntuGestureQml_SOURCES
6 AxisVelocityCalculator.cpp
6 AxisVelocityCalculator.cpp
7 Direction.cpp
7 Direction.cpp
8 DirectionalDragArea.cpp
8 DirectionalDragArea.cpp
9+ TimeSource.cpp
9)
10)
10
11
11add_definitions(-DUBUNTUGESTURES_LIBRARY)
12add_definitions(-DUBUNTUGESTURES_LIBRARY)
plugins/Ubuntu/Gestures/DirectionalDragArea.cpp+307−71
@@ -18,6 +18,75 @@
18
18
19#include <QtCore/qmath.h>
19#include <QtCore/qmath.h>
20#include <QtCore/QTimer>
20#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
21
90
22// Essentially a QTimer wrapper
91// Essentially a QTimer wrapper
23class RecognitionTimer : public UbuntuGestures::AbstractTimer
92class RecognitionTimer : public UbuntuGestures::AbstractTimer
@@ -48,9 +117,12 @@ DirectionalDragArea::DirectionalDragArea(QQuickItem *parent)
48 , m_minSpeed(0)
117 , m_minSpeed(0)
49 , m_maxSilenceTime(200)
118 , m_maxSilenceTime(200)
50 , m_silenceTime(0)
119 , m_silenceTime(0)
120+ , m_compositionTime(60)
51 , m_numSamplesOnLastSpeedCheck(0)
121 , m_numSamplesOnLastSpeedCheck(0)
52 , m_recognitionTimer(0)
122 , m_recognitionTimer(0)
53 , m_velocityCalculator(0)
123 , m_velocityCalculator(0)
124+ , m_timeSource(new RealTimeSource)
125+ , m_activeTouches(m_timeSource)
54{
126{
55 setRecognitionTimer(new RecognitionTimer(this));
127 setRecognitionTimer(new RecognitionTimer(this));
56 m_recognitionTimer->setInterval(60);
128 m_recognitionTimer->setInterval(60);
@@ -73,8 +145,8 @@ void DirectionalDragArea::setDirection(Direction::Type direction)
73
145
74void DirectionalDragArea::setMaxDeviation(qreal value)
146void DirectionalDragArea::setMaxDeviation(qreal value)
75{
147{
76− if (m_dampedPos.maxDelta() != value) {
148+ if (m_dampedScenePos.maxDelta() != value) {
77− m_dampedPos.setMaxDelta(value);
149+ m_dampedScenePos.setMaxDelta(value);
78 Q_EMIT maxDeviationChanged(value);
150 Q_EMIT maxDeviationChanged(value);
79 }
151 }
80}
152}
@@ -118,6 +190,14 @@ void DirectionalDragArea::setMaxSilenceTime(int value)
118 }
190 }
119}
191}
120
192
193+void DirectionalDragArea::setCompositionTime(int value)
194+{
195+ if (m_compositionTime != value) {
196+ m_compositionTime = value;
197+ Q_EMIT compositionTimeChanged(value);
198+ }
199+}
200+
121void DirectionalDragArea::setRecognitionTimer(UbuntuGestures::AbstractTimer *timer)
201void DirectionalDragArea::setRecognitionTimer(UbuntuGestures::AbstractTimer *timer)
122{
202{
123 int interval = 0;
203 int interval = 0;
@@ -141,9 +221,11 @@ void DirectionalDragArea::setRecognitionTimer(UbuntuGestures::AbstractTimer *tim
141 }
221 }
142}
222}
143
223
144−void DirectionalDragArea::setTimeSource(UbuntuGestures::TimeSource *timeSource)
224+void DirectionalDragArea::setTimeSource(const SharedTimeSource &timeSource)
145{
225{
226+ m_timeSource = timeSource;
146 m_velocityCalculator->setTimeSource(timeSource);
227 m_velocityCalculator->setTimeSource(timeSource);
228+ m_activeTouches.m_timeSource = timeSource;
147}
229}
148
230
149qreal DirectionalDragArea::distance() const
231qreal DirectionalDragArea::distance() const
@@ -186,6 +268,12 @@ qreal DirectionalDragArea::touchSceneY() const
186
268
187void DirectionalDragArea::touchEvent(QTouchEvent *event)
269void DirectionalDragArea::touchEvent(QTouchEvent *event)
188{
270{
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+
189 if (!isEnabled() || !isVisible()) {
277 if (!isEnabled() || !isVisible()) {
190 QQuickItem::touchEvent(event);
278 QQuickItem::touchEvent(event);
191 return;
279 return;
@@ -198,76 +286,124 @@ void DirectionalDragArea::touchEvent(QTouchEvent *event)
198 case Undecided:
286 case Undecided:
199 touchEvent_undecided(event);
287 touchEvent_undecided(event);
200 break;
288 break;
201− case Recognized:
289+ default: // Recognized:
202 touchEvent_recognized(event);
290 touchEvent_recognized(event);
203 break;
291 break;
204− default: // Rejected
205− touchEvent_rejected(event);
206− break;
207 }
292 }
293+
294+ m_activeTouches.update(event);
208}
295}
209
296
210void DirectionalDragArea::touchEvent_absent(QTouchEvent *event)
297void DirectionalDragArea::touchEvent_absent(QTouchEvent *event)
211{
298{
212− if ((event->touchPointStates() && (Qt::TouchPointPressed || Qt::TouchPointMoved))
299+ if (!event->touchPointStates().testFlag(Qt::TouchPointPressed)) {
213− && event->touchPoints().count() == 1) {
300+ // Nothing to see here. No touch starting in this event.
214− const QTouchEvent::TouchPoint &touchPoint = event->touchPoints()[0];
301+ return;
215− m_startPos = touchPoint.pos();
302+ }
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);
225
303
226− if (m_distanceThreshold > 0)
304+ if (isWithinTouchCompositionWindow()) {
227− setStatus(Undecided);
305+ // too close to the last touch start. So we consider them as starting roughly at the same time.
228− else
306+ // Can't be a single-touch gesture.
229− setStatus(Recognized);
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;
230 }
311 }
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);
231}
346}
232
347
233void DirectionalDragArea::touchEvent_undecided(QTouchEvent *event)
348void DirectionalDragArea::touchEvent_undecided(QTouchEvent *event)
234{
349{
235 const QTouchEvent::TouchPoint *touchPoint = fetchTargetTouchPoint(event);
350 const QTouchEvent::TouchPoint *touchPoint = fetchTargetTouchPoint(event);
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+
236− const QPointF &touchPos = touchPoint->pos();
360+ const QPointF &touchScenePos = touchPoint->scenePos();
237
361
238 if (touchPoint->state() == Qt::TouchPointReleased) {
362 if (touchPoint->state() == Qt::TouchPointReleased) {
239 // touch has ended before recognition concluded
363 // touch has ended before recognition concluded
364+ DDA_DEBUG("Touch has ended before recognition concluded");
240 setStatus(WaitingForTouch);
365 setStatus(WaitingForTouch);
241 return;
366 return;
242 }
367 }
243
368
244− if (event->touchPointStates().testFlag(Qt::TouchPointPressed)
369+ if (event->touchPointStates().testFlag(Qt::TouchPointPressed) && isWithinTouchCompositionWindow()) {
245− || event->touchPoints().count() > 1) {
246 // multi-finger drags are not accepted
370 // multi-finger drags are not accepted
371+ DDA_DEBUG("Multi-finger drags are not accepted");
247− setStatus(Rejected);
372+ setStatus(WaitingForTouch);
248 return;
373 return;
249 }
374 }
250
375
251− m_previousDampedPos.setX(m_dampedPos.x());
376+ m_previousDampedScenePos.setX(m_dampedScenePos.x());
252− m_previousDampedPos.setY(m_dampedPos.y());
377+ m_previousDampedScenePos.setY(m_dampedScenePos.y());
253− m_dampedPos.update(touchPos);
378+ m_dampedScenePos.update(touchScenePos);
254− updateVelocityCalculator(touchPos);
379+ updateVelocityCalculator(touchScenePos);
255
380
256 if (!pointInsideAllowedArea()) {
381 if (!pointInsideAllowedArea()) {
382+ DDA_DEBUG("Rejecting gesture because touch point is outside allowed area.");
257− setStatus(Rejected);
383+ setStatus(WaitingForTouch);
258 return;
384 return;
259 }
385 }
260
386
261 if (!movingInRightDirection()) {
387 if (!movingInRightDirection()) {
388+ DDA_DEBUG("Rejecting gesture becauuse touch point is moving in the wrong direction.");
262− setStatus(Rejected);
389+ setStatus(WaitingForTouch);
263 return;
390 return;
264 }
391 }
265
392
266− setPreviousPos(touchPos);
393+ setPreviousPos(touchPoint->pos());
267− setPreviousScenePos(touchPoint->scenePos());
394+ setPreviousScenePos(touchScenePos);
268
395
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+
269− if (movedFarEnough(touchPos)) {
403+ if (movedFarEnough(touchScenePos)) {
270 setStatus(Recognized);
404 setStatus(Recognized);
405+ } else {
406+ DDA_DEBUG("Didn't move far enough yet. Let's wait more.");
271 }
407 }
272}
408}
273
409
@@ -275,20 +411,18 @@ void DirectionalDragArea::touchEvent_recognized(QTouchEvent *event)
275{
411{
276 const QTouchEvent::TouchPoint *touchPoint = fetchTargetTouchPoint(event);
412 const QTouchEvent::TouchPoint *touchPoint = fetchTargetTouchPoint(event);
277
413
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.";
282 setStatus(WaitingForTouch);
418 setStatus(WaitingForTouch);
283− }
419+ } else {
284−}
420+ setPreviousPos(touchPoint->pos());
285−
421+ setPreviousScenePos(touchPoint->scenePos());
286−void DirectionalDragArea::touchEvent_rejected(QTouchEvent *event)
287−{
288− const QTouchEvent::TouchPoint *touchPoint = fetchTargetTouchPoint(event);
289
422
290− if (!touchPoint || touchPoint->state() == Qt::TouchPointReleased) {
423+ if (touchPoint->state() == Qt::TouchPointReleased) {
291− setStatus(WaitingForTouch);
424+ setStatus(WaitingForTouch);
425+ }
292 }
426 }
293}
427}
294
428
@@ -307,8 +441,8 @@ const QTouchEvent::TouchPoint *DirectionalDragArea::fetchTargetTouchPoint(QTouch
307
441
308bool DirectionalDragArea::pointInsideAllowedArea() const
442bool DirectionalDragArea::pointInsideAllowedArea() const
309{
443{
310− qreal dX = m_dampedPos.x() - m_startPos.x();
444+ qreal dX = m_dampedScenePos.x() - m_startScenePos.x();
311− qreal dY = m_dampedPos.y() - m_startPos.y();
445+ qreal dY = m_dampedScenePos.y() - m_startScenePos.y();
312
446
313 switch (m_direction) {
447 switch (m_direction) {
314 case Direction::Upwards:
448 case Direction::Upwards:
@@ -326,22 +460,26 @@ bool DirectionalDragArea::movingInRightDirection() const
326{
460{
327 switch (m_direction) {
461 switch (m_direction) {
328 case Direction::Upwards:
462 case Direction::Upwards:
329− return m_dampedPos.y() <= m_previousDampedPos.y();
463+ return m_dampedScenePos.y() <= m_previousDampedScenePos.y();
330 case Direction::Downwards:
464 case Direction::Downwards:
331− return m_dampedPos.y() >= m_previousDampedPos.y();
465+ return m_dampedScenePos.y() >= m_previousDampedScenePos.y();
332 case Direction::Leftwards:
466 case Direction::Leftwards:
333− return m_dampedPos.x() <= m_previousDampedPos.x();
467+ return m_dampedScenePos.x() <= m_previousDampedScenePos.x();
334 default: // Direction::Rightwards:
468 default: // Direction::Rightwards:
335− return m_dampedPos.x() >= m_previousDampedPos.x();
469+ return m_dampedScenePos.x() >= m_previousDampedScenePos.x();
336 }
470 }
337}
471}
338
472
339bool DirectionalDragArea::movedFarEnough(const QPointF &point) const
473bool DirectionalDragArea::movedFarEnough(const QPointF &point) const
340{
474{
475+ if (m_distanceThreshold > 0) {
341− if (Direction::isHorizontal(m_direction))
476+ if (Direction::isHorizontal(m_direction))
342− return qFabs(point.x() - m_startPos.x()) > m_distanceThreshold;
477+ return qFabs(point.x() - m_startScenePos.x()) > m_distanceThreshold;
343− else
478+ else
344− return qFabs(point.y() - m_startPos.y()) > m_distanceThreshold;
479+ return qFabs(point.y() - m_startScenePos.y()) > m_distanceThreshold;
480+ } else {
481+ return true;
482+ }
345}
483}
346
484
347void DirectionalDragArea::checkSpeed()
485void DirectionalDragArea::checkSpeed()
@@ -351,7 +489,8 @@ void DirectionalDragArea::checkSpeed()
351 qreal minSpeedMsecs = m_minSpeed / 1000.0;
489 qreal minSpeedMsecs = m_minSpeed / 1000.0;
352
490
353 if (speed < minSpeedMsecs) {
491 if (speed < minSpeedMsecs) {
492+ DDA_DEBUG("Rejecting gesture because it's below minimum speed.");
354− setStatus(Rejected);
493+ setStatus(WaitingForTouch);
355 }
494 }
356 }
495 }
357
496
@@ -359,7 +498,8 @@ void DirectionalDragArea::checkSpeed()
359 m_silenceTime += m_recognitionTimer->interval();
498 m_silenceTime += m_recognitionTimer->interval();
360
499
361 if (m_silenceTime > m_maxSilenceTime) {
500 if (m_silenceTime > m_maxSilenceTime) {
501+ DDA_DEBUG("Rejecting gesture because it's silence time has been exceeded.");
362− setStatus(Rejected);
502+ setStatus(WaitingForTouch);
363 }
503 }
364 } else {
504 } else {
365 m_silenceTime = 0;
505 m_silenceTime = 0;
@@ -381,11 +521,13 @@ void DirectionalDragArea::setStatus(DirectionalDragArea::Status newStatus)
381 m_status = newStatus;
521 m_status = newStatus;
382 Q_EMIT statusChanged(m_status);
522 Q_EMIT statusChanged(m_status);
383
523
524+ #if DIRECTIONALDRAGAREA_DEBUG
525+ qDebug() << "[DDA]" << statusToString(oldStatus) << "->" << statusToString(newStatus);
526+ #endif
527+
384 switch (newStatus) {
528 switch (newStatus) {
385 case WaitingForTouch:
529 case WaitingForTouch:
386− if (oldStatus != DirectionalDragArea::Rejected) {
387− Q_EMIT draggingChanged(false);
530+ Q_EMIT draggingChanged(false);
388− }
389 break;
531 break;
390 case Undecided:
532 case Undecided:
391 m_recognitionTimer->start();
533 m_recognitionTimer->start();
@@ -395,9 +537,6 @@ void DirectionalDragArea::setStatus(DirectionalDragArea::Status newStatus)
395 if (oldStatus == WaitingForTouch)
537 if (oldStatus == WaitingForTouch)
396 Q_EMIT draggingChanged(true);
538 Q_EMIT draggingChanged(true);
397 break;
539 break;
398− case Rejected:
399− Q_EMIT draggingChanged(false);
400− break;
401 default:
540 default:
402 // no-op
541 // no-op
403 break;
542 break;
@@ -406,8 +545,6 @@ void DirectionalDragArea::setStatus(DirectionalDragArea::Status newStatus)
406
545
407void DirectionalDragArea::setPreviousPos(const QPointF &point)
546void DirectionalDragArea::setPreviousPos(const QPointF &point)
408{
547{
409− Q_ASSERT(m_status != Rejected);
410−
411 bool xChanged = m_previousPos.x() != point.x();
548 bool xChanged = m_previousPos.x() != point.x();
412 bool yChanged = m_previousPos.y() != point.y();
549 bool yChanged = m_previousPos.y() != point.y();
413
550
@@ -428,8 +565,6 @@ void DirectionalDragArea::setPreviousPos(const QPointF &point)
428
565
429void DirectionalDragArea::setPreviousScenePos(const QPointF &point)
566void DirectionalDragArea::setPreviousScenePos(const QPointF &point)
430{
567{
431− Q_ASSERT(m_status != Rejected);
432−
433 bool xChanged = m_previousScenePos.x() != point.x();
568 bool xChanged = m_previousScenePos.x() != point.x();
434 bool yChanged = m_previousScenePos.y() != point.y();
569 bool yChanged = m_previousScenePos.y() != point.y();
435
570
@@ -457,5 +592,106 @@ void DirectionalDragArea::updateVelocityCalculator(const QPointF &point)
457 }
592 }
458}
593}
459
594
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+
460// Because we are defining a new QObject-based class (RecognitionTimer) here.
696// Because we are defining a new QObject-based class (RecognitionTimer) here.
461#include "DirectionalDragArea.moc"
697#include "DirectionalDragArea.moc"
plugins/Ubuntu/Gestures/DirectionalDragArea.h+50−13
@@ -117,9 +117,17 @@ class UBUNTUGESTURES_EXPORT DirectionalDragArea : public QQuickItem {
117 Q_PROPERTY(int maxSilenceTime READ maxSilenceTime
117 Q_PROPERTY(int maxSilenceTime READ maxSilenceTime
118 WRITE setMaxSilenceTime
118 WRITE setMaxSilenceTime
119 NOTIFY maxSilenceTimeChanged)
119 NOTIFY maxSilenceTimeChanged)
120+
120 //
121 //
121 /////
122 /////
122
123
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+
123 Q_ENUMS(Direction)
131 Q_ENUMS(Direction)
124 Q_ENUMS(Status)
132 Q_ENUMS(Status)
125public:
133public:
@@ -130,26 +138,23 @@ public:
130
138
131 // Describes the state of the directional drag gesture.
139 // Describes the state of the directional drag gesture.
132 enum Status {
140 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.
134 WaitingForTouch,
143 WaitingForTouch,
135
144
136 // A touch point has landed on this area but it's not know yet whether it is
145 // A touch point has landed on this area but it's not know yet whether it is
137 // performing a drag in the correct direction.
146 // 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.
138 Undecided, //Recognizing,
149 Undecided, //Recognizing,
139
150
140 // There's a touch point in this area and it performed a drag in the correct
151 // There's a touch point in this area and it performed a drag in the correct
141 // direction.
152 // direction.
142 //
153 //
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
144 // that touch point ends. The gesture will remain in the Recognized state even if
155 // that touch point ends. The gesture will remain in the Recognized state even if
145 // the touch point starts moving in other directions or halts.
156 // the touch point starts moving in other directions or halts.
146 Recognized,
157 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
153 };
158 };
154 Status status() const { return m_status; }
159 Status status() const { return m_status; }
155
160
@@ -164,7 +169,7 @@ public:
164
169
165 bool dragging() const { return (m_status == Undecided) || (m_status == Recognized); }
170 bool dragging() const { return (m_status == Undecided) || (m_status == Recognized); }
166
171
167− qreal maxDeviation() const { return m_dampedPos.maxDelta(); }
172+ qreal maxDeviation() const { return m_dampedScenePos.maxDelta(); }
168 void setMaxDeviation(qreal value);
173 void setMaxDeviation(qreal value);
169
174
170 qreal wideningAngle() const;
175 qreal wideningAngle() const;
@@ -179,13 +184,16 @@ public:
179 int maxSilenceTime() const { return m_maxSilenceTime; }
184 int maxSilenceTime() const { return m_maxSilenceTime; }
180 void setMaxSilenceTime(int value);
185 void setMaxSilenceTime(int value);
181
186
187+ int compositionTime() const { return m_compositionTime; }
188+ void setCompositionTime(int value);
189+
182 // Replaces the existing Timer with the given one.
190 // Replaces the existing Timer with the given one.
183 //
191 //
184 // Useful for providing a fake timer when testing.
192 // Useful for providing a fake timer when testing.
185 void setRecognitionTimer(UbuntuGestures::AbstractTimer *timer);
193 void setRecognitionTimer(UbuntuGestures::AbstractTimer *timer);
186
194
187 // Useful for testing, where a fake time source can be supplied
195 // Useful for testing, where a fake time source can be supplied
188− void setTimeSource(UbuntuGestures::TimeSource *timeSource);
196+ void setTimeSource(const UbuntuGestures::SharedTimeSource &timeSource);
189
197
190Q_SIGNALS:
198Q_SIGNALS:
191 void directionChanged(Direction::Type direction);
199 void directionChanged(Direction::Type direction);
@@ -198,6 +206,7 @@ Q_SIGNALS:
198 void distanceThresholdChanged(qreal value);
206 void distanceThresholdChanged(qreal value);
199 void minSpeedChanged(qreal value);
207 void minSpeedChanged(qreal value);
200 void maxSilenceTimeChanged(int value);
208 void maxSilenceTimeChanged(int value);
209+ void compositionTimeChanged(int value);
201 void touchXChanged(qreal value);
210 void touchXChanged(qreal value);
202 void touchYChanged(qreal value);
211 void touchYChanged(qreal value);
203 void touchSceneXChanged(qreal value);
212 void touchSceneXChanged(qreal value);
@@ -213,7 +222,6 @@ private:
213 void touchEvent_absent(QTouchEvent *event);
222 void touchEvent_absent(QTouchEvent *event);
214 void touchEvent_undecided(QTouchEvent *event);
223 void touchEvent_undecided(QTouchEvent *event);
215 void touchEvent_recognized(QTouchEvent *event);
224 void touchEvent_recognized(QTouchEvent *event);
216− void touchEvent_rejected(QTouchEvent *event);
217 bool pointInsideAllowedArea() const;
225 bool pointInsideAllowedArea() const;
218 bool movingInRightDirection() const;
226 bool movingInRightDirection() const;
219 bool movedFarEnough(const QPointF &point) const;
227 bool movedFarEnough(const QPointF &point) const;
@@ -222,6 +230,7 @@ private:
222 void setPreviousPos(const QPointF &point);
230 void setPreviousPos(const QPointF &point);
223 void setPreviousScenePos(const QPointF &point);
231 void setPreviousScenePos(const QPointF &point);
224 void updateVelocityCalculator(const QPointF &point);
232 void updateVelocityCalculator(const QPointF &point);
233+ bool isWithinTouchCompositionWindow();
225
234
226 Status m_status;
235 Status m_status;
227
236
@@ -233,8 +242,8 @@ private:
233
242
234 // A movement damper is used in some of the gesture recognition calculations
243 // A movement damper is used in some of the gesture recognition calculations
235 // to get rid of noise or small oscillations in the touch position.
244 // to get rid of noise or small oscillations in the touch position.
236− DampedPointF m_dampedPos;
245+ DampedPointF m_dampedScenePos;
237− QPointF m_previousDampedPos;
246+ QPointF m_previousDampedScenePos;
238
247
239 Direction::Type m_direction;
248 Direction::Type m_direction;
240 qreal m_wideningAngle; // in degrees
249 qreal m_wideningAngle; // in degrees
@@ -243,9 +252,37 @@ private:
243 qreal m_minSpeed;
252 qreal m_minSpeed;
244 int m_maxSilenceTime; // in milliseconds
253 int m_maxSilenceTime; // in milliseconds
245 int m_silenceTime; // in milliseconds
254 int m_silenceTime; // in milliseconds
255+ int m_compositionTime; // in milliseconds
246 int m_numSamplesOnLastSpeedCheck;
256 int m_numSamplesOnLastSpeedCheck;
247 UbuntuGestures::AbstractTimer *m_recognitionTimer;
257 UbuntuGestures::AbstractTimer *m_recognitionTimer;
248 AxisVelocityCalculator *m_velocityCalculator;
258 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;
249};
286};
250
287
251#endif // DIRECTIONAL_DRAG_AREA_H
288#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−69
@@ -1,71 +1,2 @@
1−# export_qmlplugin macro
2−include(Plugins)
3−
4add_subdirectory(Indicators)
1add_subdirectory(Indicators)
5−
6−# Dependencies
7−include(FindPkgConfig)
8−pkg_check_modules(QTDEE REQUIRED libdee-qt5>=3.2)
9−pkg_check_modules(UNITYCORE REQUIRED unity-core-6.0>=7.1.1)
10−
11−include_directories(
12− ${CMAKE_CURRENT_SOURCE_DIR}
13− ${CMAKE_CURRENT_BINARY_DIR}
14− ${QTDEE_INCLUDE_DIRS}
15− ${UNITYCORE_INCLUDE_DIRS}
16− ${Qt5DBus_INCLUDE_DIRS}
17−)
18−
19−set(QMLPLUGIN_SRC
20− abstractfilteroption.cpp
21− scope.cpp
22− scopes.cpp
23− categories.cpp
24− checkoptionfilter.cpp
25− filter.cpp
26− filteroption.cpp
27− filters.cpp
28− genericoptionsmodel.cpp
29− ratingoptionsmodel.cpp
30− unityoptionsmodel.cpp
31− categoryresults.cpp
32− plugin.cpp
33− multirangefilter.cpp
34− radiooptionfilter.cpp
35− ratingsfilter.cpp
36− ratingfilteroption.cpp
37− bottombarvisibilitycommunicatorshell.cpp
38− applicationpreview.cpp
39− genericpreview.cpp
40− moviepreview.cpp
41− musicpreview.cpp
42− preview.cpp
43− previewaction.cpp
44− previewinfohint.cpp
45− result.cpp
46− showallfilteroption.cpp
47− signalslist.cpp
48− socialpreview.cpp
49− socialpreviewcomment.cpp
50− iconutils.cpp
51− variantutils.cpp
52−)
53−
54−add_library(Unity-qml MODULE
55− ${QMLPLUGIN_SRC}
56− )
57−
58−target_link_libraries(Unity-qml
59− ${QTDEE_LDFLAGS}
60− ${UNITYCORE_LDFLAGS}
61− ${Qt5DBus_LIBRARIES}
62− ${Qt5Gui_LIBRARIES}
63− )
64−
65−qt5_use_modules(Unity-qml Qml)
66−
67−# export the qmldir qmltypes and plugin files
68−export_qmlfiles(Unity Unity)
69−export_qmlplugin(Unity 0.1 Unity TARGETS Unity-qml)
70−
71add_subdirectory(Launcher)
2add_subdirectory(Launcher)
plugins/Unity/Indicators/indicator.cpp+8−16
@@ -31,32 +31,24 @@ Indicator::~Indicator()
31{
31{
32}
32}
33
33
34−void Indicator::init(const QString& busName, const QSettings& settings)
34+void Indicator::init(const QString &profile, const QString& busName, const QSettings& settings)
35{
35{
36 setId(settings.value("Indicator Service/Name").toString());
36 setId(settings.value("Indicator Service/Name").toString());
37− setPosition(settings.value("Indicator Service/Position", QVariant::fromValue(0)).toInt());
38
37
39− QString actionObjectPath = settings.value("Indicator Service/ObjectPath").toString();
38+ QVariant pos = settings.value(profile + "/Position");
40−
39+ if (!pos.isValid())
41− QVariantMap mapMenuObjectPaths;
40+ pos = settings.value("Indicator Service/Position", QVariant::fromValue(0));
42− Q_FOREACH(const QString& childGroup, settings.childGroups())
41+ setPosition(pos.toInt());
43− {
44− if (childGroup == "Indicator Service")
45− continue;
46
42
47− QString menuPath = childGroup+"/ObjectPath";
43+ QString actionObjectPath = settings.value("Indicator Service/ObjectPath").toString();
48− if (settings.contains(menuPath))
44+ QString menuObjectPath = settings.value(profile + "/ObjectPath").toString();
49− {
50− mapMenuObjectPaths[childGroup] = settings.value(menuPath).toString();
51− }
52− }
53
45
54 QVariantMap properties;
46 QVariantMap properties;
55 properties.clear();
47 properties.clear();
56 properties.insert("busType", 1);
48 properties.insert("busType", 1);
57 properties.insert("busName", busName);
49 properties.insert("busName", busName);
58 properties.insert("actionsObjectPath", actionObjectPath);
50 properties.insert("actionsObjectPath", actionObjectPath);
59− properties.insert("menuObjectPaths", mapMenuObjectPaths);
51+ properties.insert("menuObjectPath", menuObjectPath);
60 setIndicatorProperties(properties);
52 setIndicatorProperties(properties);
61}
53}
62
54
plugins/Unity/Indicators/indicator.h+1−1
@@ -35,7 +35,7 @@ public:
35 Indicator(QObject *parent = 0);
35 Indicator(QObject *parent = 0);
36 virtual ~Indicator();
36 virtual ~Indicator();
37
37
38− void init(const QString& busName, const QSettings& settings);
38+ void init(const QString &profile, const QString& busName, const QSettings& settings);
39
39
40 QString identifier() const;
40 QString identifier() const;
41 int position() const;
41 int position() const;
plugins/Unity/Indicators/indicatorsmanager.cpp+3−1
@@ -26,6 +26,8 @@
26
26
27#include "paths.h"
27#include "paths.h"
28
28
29+const QString profile = "phone";
30+
29
31
30class IndicatorsManager::IndicatorData
32class IndicatorsManager::IndicatorData
31{
33{
@@ -298,7 +300,7 @@ Indicator::Ptr IndicatorsManager::indicator(const QString& indicator_name)
298 Indicator::Ptr new_indicator(new Indicator(this));
300 Indicator::Ptr new_indicator(new Indicator(this));
299 data->m_indicator = new_indicator;
301 data->m_indicator = new_indicator;
300 QSettings settings(data->m_fileInfo.absoluteFilePath(), QSettings::IniFormat, this);
302 QSettings settings(data->m_fileInfo.absoluteFilePath(), QSettings::IniFormat, this);
301− new_indicator->init(data->m_fileInfo.fileName(), settings);
303+ new_indicator->init(profile, data->m_fileInfo.fileName(), settings);
302 return new_indicator;
304 return new_indicator;
303}
305}
304
306
plugins/Unity/Indicators/qml/IndicatorBase.qml+3−4
@@ -24,16 +24,15 @@ import Unity.Indicators 0.1 as Indicators
24Item {
24Item {
25 id: indicatorItem
25 id: indicatorItem
26
26
27− enabled: menuObjectPaths.hasOwnProperty(device)
27+ enabled: menuObjectPath != ""
28
28
29 //const
29 //const
30 property string busName
30 property string busName
31 property string actionsObjectPath
31 property string actionsObjectPath
32− property var menuObjectPaths: undefined
32+ property string menuObjectPath
33− readonly property string device: "phone"
34 property string rootMenuType: "com.canonical.indicator.root"
33 property string rootMenuType: "com.canonical.indicator.root"
35
34
36− property string deviceMenuObjectPath: menuObjectPaths.hasOwnProperty(device) ? menuObjectPaths[device] : ""
35+ property string deviceMenuObjectPath: menuObjectPath
37
36
38 property alias menuModel: cachedModel.model
37 property alias menuModel: cachedModel.model
39
38
plugins/Unity/Indicators/qml/IndicatorWidget.qml+1−1
@@ -24,5 +24,5 @@ IndicatorBase {
24 id: indicatorWidget
24 id: indicatorWidget
25
25
26 enabled: false
26 enabled: false
27− property int iconSize: height - units.gu(0.5)
27+ property int iconSize: height
28}
28}
plugins/Unity/Indicators/unitymenumodelstack.cpp+98−7
@@ -19,6 +19,64 @@
19
19
20#include "unitymenumodelstack.h"
20#include "unitymenumodelstack.h"
21
21
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+
22UnityMenuModelStack::UnityMenuModelStack(QObject* parent)
80UnityMenuModelStack::UnityMenuModelStack(QObject* parent)
23 : QObject(parent)
81 : QObject(parent)
24{
82{
@@ -26,31 +84,44 @@ UnityMenuModelStack::UnityMenuModelStack(QObject* parent)
26
84
27UnityMenuModelStack::~UnityMenuModelStack()
85UnityMenuModelStack::~UnityMenuModelStack()
28{
86{
87+ qDeleteAll(m_menuModels);
88+ m_menuModels.clear();
29}
89}
30
90
31UnityMenuModel* UnityMenuModelStack::head() const
91UnityMenuModel* UnityMenuModelStack::head() const
32{
92{
33− return !m_menuModels.isEmpty() ? m_menuModels.first() : NULL;
93+ return !m_menuModels.isEmpty() ? m_menuModels.first()->model() : NULL;
34}
94}
35
95
36void UnityMenuModelStack::setHead(UnityMenuModel* model)
96void UnityMenuModelStack::setHead(UnityMenuModel* model)
37{
97{
38 if (head() != model) {
98 if (head() != model) {
99+ qDeleteAll(m_menuModels);
39 m_menuModels.clear();
100 m_menuModels.clear();
101+
40− push(model);
102+ push(model, 0);
41 Q_EMIT headChanged(model);
103 Q_EMIT headChanged(model);
42 }
104 }
43}
105}
44
106
45UnityMenuModel* UnityMenuModelStack::tail() const
107UnityMenuModel* UnityMenuModelStack::tail() const
46{
108{
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();
48}
115}
49
116
50−void UnityMenuModelStack::push(UnityMenuModel* model)
117+void UnityMenuModelStack::push(UnityMenuModel* model, int index)
51{
118{
119+ UnityMenuModelEntry* entry = new UnityMenuModelEntry(model, tail(), index);
120+ QObject::connect(entry, SIGNAL(remove()), SLOT(onRemove()));
121+
52− m_menuModels << model;
122+ m_menuModels << entry;
53 Q_EMIT tailChanged(model);
123 Q_EMIT tailChanged(model);
124+ Q_EMIT countChanged(m_menuModels.count());
54}
125}
55
126
56UnityMenuModel* UnityMenuModelStack::pop()
127UnityMenuModel* UnityMenuModelStack::pop()
@@ -58,12 +129,32 @@ UnityMenuModel* UnityMenuModelStack::pop()
58 if (m_menuModels.isEmpty()) {
129 if (m_menuModels.isEmpty()) {
59 return NULL;
130 return NULL;
60 }
131 }
61− UnityMenuModel* model = m_menuModels.takeLast();
132+ UnityMenuModelEntry* entry = m_menuModels.takeLast();
133+ UnityMenuModel* model = entry->model();
134+ entry->deleteLater();
62
135
63 Q_EMIT tailChanged(tail());
136 Q_EMIT tailChanged(tail());
64 if (m_menuModels.isEmpty()) {
137 if (m_menuModels.isEmpty()) {
65 Q_EMIT headChanged(NULL);
138 Q_EMIT headChanged(NULL);
66 }
139 }
140+ Q_EMIT countChanged(m_menuModels.count());
67
141
68 return model;
142 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 @@
25#include <QObject>
25#include <QObject>
26#include <QList>
26#include <QList>
27
27
28+class UnityMenuModelEntry;
28class UnityMenuModel;
29class UnityMenuModel;
29
30
30// A LIFO queue for storing the current submenu of a UnityMenuModel.
31// A LIFO queue for storing the current submenu of a UnityMenuModel.
@@ -37,6 +38,7 @@ class UNITYINDICATORS_EXPORT UnityMenuModelStack : public QObject
37 Q_OBJECT
38 Q_OBJECT
38 Q_PROPERTY(UnityMenuModel* head READ head WRITE setHead NOTIFY headChanged)
39 Q_PROPERTY(UnityMenuModel* head READ head WRITE setHead NOTIFY headChanged)
39 Q_PROPERTY(UnityMenuModel* tail READ tail NOTIFY tailChanged)
40 Q_PROPERTY(UnityMenuModel* tail READ tail NOTIFY tailChanged)
41+ Q_PROPERTY(int count READ count NOTIFY countChanged)
40public:
42public:
41 UnityMenuModelStack(QObject*parent=NULL);
43 UnityMenuModelStack(QObject*parent=NULL);
42 ~UnityMenuModelStack();
44 ~UnityMenuModelStack();
@@ -46,15 +48,21 @@ public:
46
48
47 UnityMenuModel* tail() const;
49 UnityMenuModel* tail() const;
48
50
51+ int count() const;
52+
49− Q_INVOKABLE void push(UnityMenuModel* model);
53+ Q_INVOKABLE void push(UnityMenuModel* model, int menuIndex);
50 Q_INVOKABLE UnityMenuModel* pop();
54 Q_INVOKABLE UnityMenuModel* pop();
51
55
52Q_SIGNALS:
56Q_SIGNALS:
53 void headChanged(UnityMenuModel* head);
57 void headChanged(UnityMenuModel* head);
54 void tailChanged(UnityMenuModel* tail);
58 void tailChanged(UnityMenuModel* tail);
59+ void countChanged(int count);
60+
61+private Q_SLOTS:
62+ void onRemove();
55
63
56private:
64private:
57− QList<UnityMenuModel*> m_menuModels;
65+ QList<UnityMenuModelEntry*> m_menuModels;
58};
66};
59
67
60#endif // UNITYMENUMODELSTACK_H
68#endif // UNITYMENUMODELSTACK_H
plugins/Unity/Launcher/launcheritem.cpp+4−2
@@ -20,6 +20,8 @@
20#include "launcheritem.h"
20#include "launcheritem.h"
21#include "quicklistmodel.h"
21#include "quicklistmodel.h"
22
22
23+#include <libintl.h>
24+
23LauncherItem::LauncherItem(const QString &appId, const QString &name, const QString &icon, QObject *parent) :
25LauncherItem::LauncherItem(const QString &appId, const QString &name, const QString &icon, QObject *parent) :
24 LauncherItemInterface(parent),
26 LauncherItemInterface(parent),
25 m_appId(appId),
27 m_appId(appId),
@@ -38,7 +40,7 @@ LauncherItem::LauncherItem(const QString &appId, const QString &name, const QStr
38 m_quickList->appendAction(nameAction);
40 m_quickList->appendAction(nameAction);
39 QuickListEntry pinningAction;
41 QuickListEntry pinningAction;
40 pinningAction.setActionId("pin_item");
42 pinningAction.setActionId("pin_item");
41− pinningAction.setText("Pin to Launcher");
43+ pinningAction.setText(gettext("Lock to Launcher"));
42 m_quickList->appendAction(pinningAction);
44 m_quickList->appendAction(pinningAction);
43}
45}
44
46
@@ -68,7 +70,7 @@ void LauncherItem::setPinned(bool pinned)
68 m_pinned = pinned;
70 m_pinned = pinned;
69 QuickListEntry entry;
71 QuickListEntry entry;
70 entry.setActionId("pin_item");
72 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"));
72 m_quickList->updateAction(entry);
74 m_quickList->updateAction(entry);
73 Q_EMIT pinnedChanged(pinned);
75 Q_EMIT pinnedChanged(pinned);
74 }
76 }
plugins/Unity/abstractfilteroption.hdeleted−58
@@ -1,58 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#ifndef ABSTRACTFILTEROPTION_H
21−#define ABSTRACTFILTEROPTION_H
22−
23−// Qt
24−#include <QObject>
25−#include <QMetaType>
26−
27−class Q_DECL_EXPORT AbstractFilterOption : public QObject
28−{
29− Q_OBJECT
30−
31− Q_PROPERTY(QString id READ id NOTIFY idChanged)
32− Q_PROPERTY(QString name READ name NOTIFY nameChanged)
33− Q_PROPERTY(QString iconHint READ iconHint NOTIFY iconHintChanged)
34− Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
35−
36−public:
37− /* getters */
38− virtual QString id() const = 0;
39− virtual QString name() const = 0;
40− virtual QString iconHint() const = 0;
41− virtual bool active() const = 0;
42−
43− /* setters */
44− virtual void setActive(bool active) = 0;
45−
46−protected:
47− AbstractFilterOption(QObject *parent);
48−
49−Q_SIGNALS:
50− void idChanged(const QString &);
51− void nameChanged(const QString &);
52− void iconHintChanged(const QString &);
53− void activeChanged(bool);
54−};
55−
56−Q_DECLARE_METATYPE(AbstractFilterOption*)
57−
58−#endif // ABSTRACTFILTEROPTION_H
plugins/Unity/applicationpreview.cppdeleted−100
@@ -1,100 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−// local
21−#include "applicationpreview.h"
22−#include "iconutils.h"
23−
24−#include <QDebug>
25−
26−ApplicationPreview::ApplicationPreview(QObject *parent):
27− Preview(parent),
28− m_unityAppPreview(nullptr)
29−{
30−}
31−
32−QString ApplicationPreview::lastUpdate() const
33−{
34− if (m_unityAppPreview) {
35− return QString::fromStdString(m_unityAppPreview->last_update());
36− } else {
37− qWarning() << "Preview not set";
38− }
39− return QString();
40−}
41−
42−QString ApplicationPreview::copyright() const
43−{
44− if (m_unityAppPreview) {
45− return QString::fromStdString(m_unityAppPreview->copyright());
46− } else {
47− qWarning() << "Preview not set";
48− }
49− return QString();
50−}
51−
52−QString ApplicationPreview::license() const
53−{
54− if (m_unityAppPreview) {
55− return QString::fromStdString(m_unityAppPreview->license());
56− } else {
57− qWarning() << "Preview not set";
58− }
59− return QString();
60−}
61−
62−QString ApplicationPreview::appIcon() const
63−{
64− if (m_unityAppPreview) {
65− auto giconString = g_icon_to_string(m_unityAppPreview->app_icon());
66− QString result(gIconToDeclarativeImageProviderString(QString::fromUtf8(giconString)));
67− g_free(giconString);
68− return result;
69− } else {
70− qWarning() << "Preview not set";
71− }
72− return QString();
73−}
74−
75−float ApplicationPreview::rating() const
76−{
77− if (m_unityAppPreview) {
78− return m_unityAppPreview->rating();
79− } else {
80− qWarning() << "Preview not set";
81− }
82− return 0.0f;
83−}
84−
85−unsigned int ApplicationPreview::numRatings() const
86−{
87− if (m_unityAppPreview) {
88− return m_unityAppPreview->num_ratings();
89− } else {
90− qWarning() << "Preview not set";
91− }
92− return 0;
93−}
94−
95−void ApplicationPreview::setUnityPreview(unity::dash::Preview::Ptr unityPreview)
96−{
97− m_unityAppPreview = std::dynamic_pointer_cast<unity::dash::ApplicationPreview>(unityPreview);
98−
99− Q_EMIT previewChanged();
100−}
plugins/Unity/applicationpreview.hdeleted−66
@@ -1,66 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#ifndef APPLICATIONPREVIEW_H
21−#define APPLICATIONPREVIEW_H
22−
23−// local
24−#include "preview.h"
25−
26−// Qt
27−#include <QObject>
28−#include <QMetaType>
29−
30−// libunity-core
31−#include <UnityCore/ApplicationPreview.h>
32−
33−class Q_DECL_EXPORT ApplicationPreview: public Preview
34−{
35− Q_OBJECT
36−
37− Q_PROPERTY(QString lastUpdate READ lastUpdate NOTIFY previewChanged)
38− Q_PROPERTY(QString copyright READ copyright NOTIFY previewChanged)
39− Q_PROPERTY(QString license READ license NOTIFY previewChanged)
40− Q_PROPERTY(QString appIcon READ appIcon NOTIFY previewChanged)
41− Q_PROPERTY(float rating READ rating NOTIFY previewChanged)
42− Q_PROPERTY(unsigned int numRatings READ numRatings NOTIFY previewChanged)
43−
44−public:
45− explicit ApplicationPreview(QObject *parent = 0);
46−
47− QString lastUpdate() const;
48− QString copyright() const;
49− QString license() const;
50− QString appIcon() const;
51− float rating() const;
52− unsigned int numRatings() const;
53−
54−Q_SIGNALS:
55− void previewChanged();
56−
57−protected:
58− void setUnityPreview(unity::dash::Preview::Ptr unityPreview) override;
59−
60−private:
61− unity::dash::ApplicationPreview::Ptr m_unityAppPreview;
62−};
63−
64−Q_DECLARE_METATYPE(ApplicationPreview *)
65−
66−#endif
plugins/Unity/categories.cppdeleted−299
@@ -1,299 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Michał Sawicz <michal.sawicz@canonical.com>
6− * Michal Hruby <michal.hruby@canonical.com>
7− *
8− * This program is free software; you can redistribute it and/or modify
9− * it under the terms of the GNU General Public License as published by
10− * the Free Software Foundation; version 3.
11− *
12− * This program is distributed in the hope that it will be useful,
13− * but WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15− * GNU General Public License for more details.
16− *
17− * You should have received a copy of the GNU General Public License
18− * along with this program. If not, see <http://www.gnu.org/licenses/>.
19− */
20−
21−// self
22−#include "categories.h"
23−#include "categoryresults.h"
24−#include <QDebug>
25−
26−// TODO: use something from libunity once it's public
27−enum CategoryColumn {
28− ID,
29− DISPLAY_NAME,
30− ICON_HINT,
31− RENDERER_NAME,
32− HINTS
33−};
34−
35−Categories::Categories(QObject* parent)
36− : DeeListModel(parent)
37−{
38− m_roles[Categories::RoleCategoryId] = "categoryId";
39− m_roles[Categories::RoleName] = "name";
40− m_roles[Categories::RoleIcon] = "icon";
41− m_roles[Categories::RoleRenderer] = "renderer";
42− m_roles[Categories::RoleContentType] = "contentType";
43− m_roles[Categories::RoleRendererHint] = "rendererHint";
44− m_roles[Categories::RoleProgressSource] = "progressSource";
45− m_roles[Categories::RoleHints] = "hints";
46− m_roles[Categories::RoleResults] = "results";
47− m_roles[Categories::RoleCount] = "count";
48−
49− // TODO This should not be needed but accumulatting the count changes
50− // makes the visualization more stable and also makes crashes on fast
51− // change of the search term harder to reproduce
52− m_timer.setSingleShot(true);
53− m_timer.setInterval(50);
54− connect(&m_timer, &QTimer::timeout, this, &Categories::onEmitCountChanged);
55−}
56−
57−DeeListModel*
58−Categories::getResults(int index) const
59−{
60− if (!m_results.contains(index)) {
61− CategoryResults* results = new CategoryResults(const_cast<Categories*>(this));
62− results->setCategoryIndex(index);
63− connect(results, &DeeListModel::countChanged, this, &Categories::onCountChanged);
64−
65− unsigned categoryIndex = static_cast<unsigned>(index);
66− auto unity_results = m_unityScope->GetResultsForCategory(categoryIndex);
67− if (unity_results) {
68− results->setModel(unity_results->model());
69− } else {
70− // No results model returned by unity core; this can be the case when the global
71− // results model of this scope is still not set in unity core. Don't set backend
72− // model in DeeListModel - it will still beahve properly as an empty model. Since
73− // we're connected to the category model change signal, and it is set by unity core
74− // at the same time as results model (on channel opening), we'll reset category
75− // results models with proper models when we're notifed again.
76− qWarning() << "No results model for category" << categoryIndex;
77− }
78−
79− m_results.insert(index, results);
80− }
81−
82− return m_results[index];
83−}
84−
85−void Categories::onCategoriesModelChanged(unity::glib::Object<DeeModel> model)
86−{
87− m_updatedCategories.clear();
88− // FIXME: this might destroy the renderer view and re-create it, optimize?
89− Q_FOREACH(DeeListModel* model, m_results) {
90− delete model;
91− }
92− m_results.clear();
93− m_categoryOrder.clear();
94−
95− setModel(model);
96−}
97−
98−void Categories::onCategoryOrderChanged(const std::vector<unsigned int>& cat_order)
99−{
100− for (unsigned int pos = 0; pos<cat_order.size(); pos++)
101− {
102− unsigned int cat = cat_order[pos];
103− const int old_pos = m_categoryOrder.indexOf(cat);
104−
105− if (old_pos < 0) {
106− qWarning() << "No such category index:" << cat;
107− continue;
108− }
109−
110− if (static_cast<int>(pos) != old_pos) {
111− int target_pos = pos;
112− if (target_pos > old_pos)
113− target_pos++;
114− const bool status = beginMoveRows(QModelIndex(), old_pos, old_pos, QModelIndex(), target_pos);
115− if (status)
116− m_categoryOrder.move(old_pos, pos);
117− else
118− qWarning() << "beginMoveRows failed:" << old_pos << target_pos;
119− endMoveRows();
120− }
121− }
122−}
123−
124−void
125−Categories::setUnityScope(const unity::dash::Scope::Ptr& scope)
126−{
127− m_unityScope = scope;
128−
129− // no need to call this, we'll get notified
130− //setModel(m_unityScope->categories()->model());
131−
132− m_signals.disconnectAll();
133− m_signals << m_unityScope->categories()->model.changed.connect(sigc::mem_fun(this, &Categories::onCategoriesModelChanged));
134−
135− // FIXME: Don't handle category order changes for now as it causes UI issues (https://bugs.launchpad.net/unity8/+bug/1239584).
136− //m_signals << m_unityScope->category_order.changed.connect(sigc::mem_fun(this, &Categories::onCategoryOrderChanged));
137−}
138−
139−void
140−Categories::onCountChanged()
141−{
142− CategoryResults* results = qobject_cast<CategoryResults*>(sender());
143− if (results) {
144− if (!m_updatedCategories.contains(results->categoryIndex())) {
145− m_updatedCategories << results->categoryIndex();
146− }
147− m_timer.start();
148− }
149−}
150−
151−void Categories::onRowCountChanged()
152−{
153− QAbstractItemModel* model = qobject_cast<QAbstractItemModel*>(sender());
154− // find the corresponding category index
155− for (auto iter = m_overriddenCategories.begin(); iter != m_overriddenCategories.end(); ++iter) {
156− if (iter.value() == model) {
157− for (int i = 0; i < rowCount(); i++) {
158− auto id = data(index(i), RoleCategoryId).toString();
159− if (id != iter.key()) continue;
160− QVector<int> roles;
161− roles.append(RoleCount);
162− QModelIndex changedIndex = index(i);
163− Q_EMIT dataChanged(changedIndex, changedIndex, roles);
164− break;
165− }
166− }
167− }
168−}
169−
170−void
171−Categories::onEmitCountChanged()
172−{
173− QVector<int> roles;
174− roles.append(Categories::RoleCount);
175− Q_FOREACH(int categoryIndex, m_updatedCategories) {
176− if (!m_results.contains(categoryIndex)) continue;
177− const int realIndex = m_categoryOrder.indexOf(categoryIndex);
178− const QModelIndex changedIndex = index(realIndex);
179− Q_EMIT dataChanged(changedIndex, changedIndex, roles);
180− }
181− m_updatedCategories.clear();
182−}
183−
184−QHash<int, QByteArray>
185−Categories::roleNames() const
186−{
187− return m_roles;
188−}
189−
190−void Categories::onOverrideModelDestroyed()
191−{
192− QObject* model = sender();
193− auto iter = m_overriddenCategories.begin();
194− while (iter != m_overriddenCategories.end()) {
195− if (iter.value() == model) {
196− iter = m_overriddenCategories.erase(iter);
197− continue;
198− }
199− ++iter;
200− }
201−}
202−
203−void Categories::overrideResults(const QString& categoryId, QAbstractItemModel* model)
204−{
205− m_overriddenCategories[categoryId] = model;
206− // watch the model
207− connect(model, &QObject::destroyed, this, &Categories::onOverrideModelDestroyed);
208− connect(model, &QAbstractItemModel::rowsInserted, this, &Categories::onRowCountChanged);
209− connect(model, &QAbstractItemModel::rowsRemoved, this, &Categories::onRowCountChanged);
210− connect(model, &QAbstractItemModel::modelReset, this, &Categories::onRowCountChanged);
211−
212− // emit the dataChanged signal if the category is already in the model
213− for (int i = 0; i < rowCount(); i++) {
214− auto id = data(index(i), RoleCategoryId).toString();
215− if (id != categoryId) continue;
216− QVector<int> roles;
217− roles.append(RoleCount);
218− roles.append(RoleResults);
219− QModelIndex changedIndex = index(i);
220− Q_EMIT dataChanged(changedIndex, changedIndex, roles);
221− break;
222− }
223−}
224−
225−QVariant
226−Categories::data(const QModelIndex& index, int role) const
227−{
228− if (!index.isValid()) {
229− return QVariant();
230− }
231−
232− if (m_categoryOrder.size() != rowCount())
233− {
234− // populate category order vector with 0..n
235− m_categoryOrder.clear();
236− const unsigned int lim = rowCount();
237− for (unsigned int i = 0; i<lim; i++) {
238− m_categoryOrder.append(i);
239− }
240− }
241−
242− int realRow = index.row();
243− if (index.row() < m_categoryOrder.size()) {
244− realRow = m_categoryOrder[index.row()];
245− } else {
246− qWarning() << "Invalid index" << index.row();
247− return QVariant();
248− }
249−
250− const QModelIndex realIndex = createIndex(realRow, index.column());
251−
252− switch (role) {
253− case RoleCategoryId:
254− return DeeListModel::data(realIndex, CategoryColumn::ID);
255− case RoleName:
256− return DeeListModel::data(realIndex, CategoryColumn::DISPLAY_NAME);
257− case RoleIcon:
258− return DeeListModel::data(realIndex, CategoryColumn::ICON_HINT);
259− case RoleRenderer:
260− return DeeListModel::data(realIndex, CategoryColumn::RENDERER_NAME);
261− case RoleContentType:
262− {
263− auto hints = DeeListModel::data(realIndex, CategoryColumn::HINTS).toHash();
264− return hints.contains("content-type") ? hints["content-type"] : QVariant(QString("default"));
265− }
266− case RoleRendererHint:
267− {
268− auto hints = DeeListModel::data(realIndex, CategoryColumn::HINTS).toHash();
269− return hints.contains("renderer-hint") ? hints["renderer-hint"] : QVariant(QString());
270− }
271− case RoleProgressSource:
272− {
273− auto hints = DeeListModel::data(realIndex, CategoryColumn::HINTS).toHash();
274− return hints.contains("progress-source") ? hints["progress-source"] : QVariant();
275− }
276− case RoleHints:
277− return DeeListModel::data(realIndex, CategoryColumn::HINTS);
278− case RoleResults:
279− if (m_overriddenCategories.size() > 0)
280− {
281− auto id = DeeListModel::data(realIndex, CategoryColumn::ID).toString();
282− if (m_overriddenCategories.find(id) != m_overriddenCategories.end())
283− return QVariant::fromValue(m_overriddenCategories[id]);
284− }
285− return QVariant::fromValue(getResults(realRow));
286− case RoleCount:
287− if (m_overriddenCategories.size() > 0)
288− {
289− auto id = DeeListModel::data(realIndex, CategoryColumn::ID).toString();
290− if (m_overriddenCategories.find(id) != m_overriddenCategories.end())
291− {
292− return QVariant::fromValue(m_overriddenCategories[id]->rowCount());
293− }
294− }
295− return QVariant::fromValue(getResults(realRow)->rowCount());
296− default:
297− return QVariant();
298− }
299−}
plugins/Unity/categories.hdeleted−95
@@ -1,95 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Michał Sawicz <michal.sawicz@canonical.com>
6− * Michal Hruby <michal.hruby@canonical.com>
7− *
8− * This program is free software; you can redistribute it and/or modify
9− * it under the terms of the GNU General Public License as published by
10− * the Free Software Foundation; version 3.
11− *
12− * This program is distributed in the hope that it will be useful,
13− * but WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15− * GNU General Public License for more details.
16− *
17− * You should have received a copy of the GNU General Public License
18− * along with this program. If not, see <http://www.gnu.org/licenses/>.
19− */
20−
21−
22−#ifndef CATEGORIES_H
23−#define CATEGORIES_H
24−
25−// unity-core
26−#include <UnityCore/Scope.h>
27−
28−// dee-qt
29−#include "deelistmodel.h"
30−
31−#include <QPointer>
32−#include <QSet>
33−#include <QTimer>
34−
35−// local
36−#include "signalslist.h"
37−
38−class Categories : public DeeListModel
39−{
40− Q_OBJECT
41−
42− Q_ENUMS(Roles)
43−
44−public:
45− explicit Categories(QObject* parent = 0);
46−
47− enum Roles {
48− RoleCategoryId,
49− RoleName,
50− RoleIcon,
51− RoleRenderer,
52− RoleContentType,
53− RoleRendererHint,
54− RoleProgressSource,
55− RoleHints,
56− RoleResults,
57− RoleCount
58− };
59−
60− Q_INVOKABLE void overrideResults(const QString& categoryId, QAbstractItemModel* model);
61−
62− QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
63−
64− QHash<int, QByteArray> roleNames() const;
65−
66− /* setters */
67− void setUnityScope(const unity::dash::Scope::Ptr& scope);
68−
69−private Q_SLOTS:
70− void onCountChanged();
71− void onRowCountChanged();
72− void onEmitCountChanged();
73− void onOverrideModelDestroyed();
74−
75−private:
76− void onCategoriesModelChanged(unity::glib::Object<DeeModel> model);
77− void onCategoryOrderChanged(const std::vector<unsigned int>& cat_order);
78−
79− DeeListModel* getResults(int index) const;
80−
81− unity::dash::Scope::Ptr m_unityScope;
82− QTimer m_timer;
83− QSet<int> m_updatedCategories;
84− QHash<int, QByteArray> m_roles;
85− QMap<QString, QAbstractItemModel*> m_overriddenCategories;
86− mutable QMap<int, DeeListModel*> m_results;
87− SignalsList m_signals;
88−
89− /* Category order array contains indices of actual categories in the underlying DeeListModel.
90− It's used internally to reflect category order reported by scope.
91− */
92− mutable QList<unsigned int> m_categoryOrder;
93−};
94−
95−#endif // CATEGORIES_H
plugins/Unity/checkoptionfilter.cppdeleted−65
@@ -1,65 +0,0 @@
1−/*
2− * Copyright (C) 2011 Canonical, Ltd.
3− *
4− * Authors:
5− * Florian Boucault <florian.boucault@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−// Self
21−#include "checkoptionfilter.h"
22−
23−// local
24−#include "unityoptionsmodel.h"
25−
26−CheckOptionFilter::CheckOptionFilter(QObject *parent) :
27− Filter(parent),
28− m_unityCheckOptionFilter(nullptr),
29− m_options(nullptr)
30−{
31−}
32−
33−GenericOptionsModel* CheckOptionFilter::options() const
34−{
35− return m_options;
36−}
37−
38−void CheckOptionFilter::setUnityFilter(unity::dash::Filter::Ptr filter)
39−{
40− Filter::setUnityFilter(filter);
41− m_unityCheckOptionFilter = std::dynamic_pointer_cast<unity::dash::CheckOptionFilter>(m_unityFilter);
42− onOptionsChanged(m_unityCheckOptionFilter->options);
43−}
44−
45−void CheckOptionFilter::onOptionsChanged(unity::dash::CheckOptionFilter::CheckOptions options)
46−{
47− if (m_options != nullptr) {
48− m_signals.disconnectAll();
49− delete m_options;
50− m_options = nullptr;
51− }
52−
53− m_options = new UnityOptionsModel(this, options,
54− m_unityCheckOptionFilter->option_added,
55− m_unityCheckOptionFilter->option_removed,
56− m_unityCheckOptionFilter->show_all_button);
57−
58− connect(m_options, SIGNAL(activeChanged(AbstractFilterOption *)), m_options, SLOT(ensureTheOnlyActive(AbstractFilterOption *)));
59− connect(m_options, SIGNAL(showAllActivated()), this, SLOT(clear()));
60−
61− /* Property change signals */
62− m_signals << m_unityCheckOptionFilter->options.changed.connect(sigc::mem_fun(this, &CheckOptionFilter::onOptionsChanged));
63−
64− Q_EMIT optionsChanged();
65−}
plugins/Unity/checkoptionfilter.hdeleted−57
@@ -1,57 +0,0 @@
1−/*
2− * Copyright (C) 2011 Canonical, Ltd.
3− *
4− * Authors:
5− * Florian Boucault <florian.boucault@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#ifndef CHECKOPTIONFILTER_H
21−#define CHECKOPTIONFILTER_H
22−
23−// Qt
24−#include <QObject>
25−#include <QMetaType>
26−
27−// libunity-core
28−#include <UnityCore/CheckOptionFilter.h>
29−
30−// Local
31−#include "filter.h"
32−#include "signalslist.h"
33−
34−class Q_DECL_EXPORT CheckOptionFilter : public Filter
35−{
36− Q_OBJECT
37−
38−public:
39− explicit CheckOptionFilter(QObject *parent = nullptr);
40−
41− /* getters */
42− GenericOptionsModel* options() const override;
43−
44−protected:
45− void setUnityFilter(unity::dash::Filter::Ptr filter) override;
46−
47−private:
48− void onOptionsChanged(unity::dash::CheckOptionFilter::CheckOptions filter);
49−
50− unity::dash::CheckOptionFilter::Ptr m_unityCheckOptionFilter;
51− SignalsList m_signals;
52− GenericOptionsModel* m_options;
53−};
54−
55−Q_DECLARE_METATYPE(CheckOptionFilter*)
56−
57−#endif // CHECKOPTIONFILTER_H
plugins/Unity/filter.cppdeleted−129
@@ -1,129 +0,0 @@
1−/*
2− * Copyright (C) 2011, 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Florian Boucault <florian.boucault@canonical.com>
6− * Pawel Stolowski <pawel.stolowski@canonical.com>
7− *
8− * This program is free software; you can redistribute it and/or modify
9− * it under the terms of the GNU General Public License as published by
10− * the Free Software Foundation; version 3.
11− *
12− * This program is distributed in the hope that it will be useful,
13− * but WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15− * GNU General Public License for more details.
16− *
17− * You should have received a copy of the GNU General Public License
18− * along with this program. If not, see <http://www.gnu.org/licenses/>.
19− */
20−
21−// Self
22−#include "filter.h"
23−
24−// local
25−#include "ratingsfilter.h"
26−#include "radiooptionfilter.h"
27−#include "checkoptionfilter.h"
28−#include "multirangefilter.h"
29−
30−// libunity-core
31−#include <UnityCore/Filter.h>
32−#include <UnityCore/RatingsFilter.h>
33−#include <UnityCore/RadioOptionFilter.h>
34−#include <UnityCore/CheckOptionFilter.h>
35−#include <UnityCore/MultiRangeFilter.h>
36−
37−// Qt
38−#include <QDebug>
39−
40−Filter::Filter(QObject *parent) :
41− QObject(parent)
42−{
43−}
44−
45−QString Filter::id() const
46−{
47− if (!m_unityFilter)
48− return QString::Null();
49− return QString::fromStdString(m_unityFilter->id());
50−}
51−
52−QString Filter::name() const
53−{
54− if (!m_unityFilter)
55− return QString::Null();
56− return QString::fromStdString(m_unityFilter->name());
57−}
58−
59−QString Filter::iconHint() const
60−{
61− if (!m_unityFilter)
62− return QString::Null();
63− return QString::fromStdString(m_unityFilter->icon_hint());
64−}
65−
66−QString Filter::rendererName() const
67−{
68− if (!m_unityFilter)
69− return QString::Null();
70− return QString::fromStdString(m_unityFilter->renderer_name());
71−}
72−
73−bool Filter::visible() const
74−{
75− if (!m_unityFilter)
76− return false;
77− return m_unityFilter->visible();
78−}
79−
80−bool Filter::collapsed() const
81−{
82− if (!m_unityFilter)
83− return false;
84− return m_unityFilter->collapsed();
85−}
86−
87−bool Filter::filtering() const
88−{
89− if (!m_unityFilter)
90− return false;
91− return m_unityFilter->filtering();
92−}
93−
94−void Filter::clear()
95−{
96− if (m_unityFilter)
97− m_unityFilter->Clear();
98−}
99−
100−void Filter::setUnityFilter(unity::dash::Filter::Ptr unityFilter)
101−{
102− m_unityFilter = unityFilter;
103−}
104−
105−Filter* Filter::newFromUnityFilter(unity::dash::Filter::Ptr unityFilter)
106−{
107− Filter* filter;
108−
109− if (typeid(*unityFilter) == typeid(unity::dash::RatingsFilter)) {
110− filter = new RatingsFilter;
111− } else if (typeid(*unityFilter) == typeid(unity::dash::CheckOptionFilter)) {
112− filter = new CheckOptionFilter;
113− } else if (typeid(*unityFilter) == typeid(unity::dash::RadioOptionFilter)) {
114− filter = new RadioOptionFilter;
115− } else if (typeid(*unityFilter) == typeid(unity::dash::MultiRangeFilter)) {
116− filter = new MultiRangeFilter;
117− } else {
118− qWarning() << "Filter of unknown type: " << typeid(*unityFilter).name();
119− return nullptr;
120− }
121−
122− filter->setUnityFilter(unityFilter);
123− return filter;
124−}
125−
126−bool Filter::hasUnityFilter(unity::dash::Filter::Ptr unityFilter) const
127−{
128− return m_unityFilter == unityFilter;
129−}
plugins/Unity/filter.hdeleted−75
@@ -1,75 +0,0 @@
1−/*
2− * Copyright (C) 2011, 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Florian Boucault <florian.boucault@canonical.com>
6− * Pawel Stolowski <pawel.stolowski@canonical.com>
7− *
8− * This program is free software; you can redistribute it and/or modify
9− * it under the terms of the GNU General Public License as published by
10− * the Free Software Foundation; version 3.
11− *
12− * This program is distributed in the hope that it will be useful,
13− * but WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15− * GNU General Public License for more details.
16− *
17− * You should have received a copy of the GNU General Public License
18− * along with this program. If not, see <http://www.gnu.org/licenses/>.
19− */
20−
21−#ifndef FILTER_H
22−#define FILTER_H
23−
24−// Qt
25−#include <QObject>
26−#include <QMetaType>
27−
28−// libunity-core
29−#include <UnityCore/Filter.h>
30−
31−class GenericOptionsModel;
32−
33−class Q_DECL_EXPORT Filter : public QObject
34−{
35− Q_OBJECT
36−
37− Q_PROPERTY(QString id READ id CONSTANT)
38− Q_PROPERTY(QString name READ name CONSTANT)
39− Q_PROPERTY(QString iconHint READ iconHint CONSTANT)
40− Q_PROPERTY(QString rendererName READ rendererName CONSTANT)
41− Q_PROPERTY(bool visible READ visible CONSTANT)
42− Q_PROPERTY(bool collapsed READ collapsed CONSTANT)
43− Q_PROPERTY(bool filtering READ filtering CONSTANT)
44− Q_PROPERTY(GenericOptionsModel* options READ options NOTIFY optionsChanged)
45−
46−public:
47− explicit Filter(QObject *parent = nullptr);
48−
49− /* getters */
50− QString id() const;
51− QString name() const;
52− QString iconHint() const;
53− QString rendererName() const;
54− bool visible() const;
55− bool collapsed() const;
56− bool filtering() const;
57− virtual GenericOptionsModel* options() const = 0;
58−
59− static Filter* newFromUnityFilter(unity::dash::Filter::Ptr unityFilter);
60− bool hasUnityFilter(unity::dash::Filter::Ptr unityFilter) const;
61−
62−public Q_SLOTS:
63− void clear();
64−
65−Q_SIGNALS:
66− void optionsChanged();
67−
68−protected:
69− unity::dash::Filter::Ptr m_unityFilter;
70− virtual void setUnityFilter(unity::dash::Filter::Ptr unityFilter);
71−};
72−
73−Q_DECLARE_METATYPE(Filter*)
74−
75−#endif // FILTER_H
plugins/Unity/filteroption.cppdeleted−91
@@ -1,91 +0,0 @@
1−/*
2− * Copyright (C) 2011, 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Florian Boucault <florian.boucault@canonical.com>
6− * Pawel Stolowski <pawel.stolowski@canonical.com>
7− *
8− * This program is free software; you can redistribute it and/or modify
9− * it under the terms of the GNU General Public License as published by
10− * the Free Software Foundation; version 3.
11− *
12− * This program is distributed in the hope that it will be useful,
13− * but WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15− * GNU General Public License for more details.
16− *
17− * You should have received a copy of the GNU General Public License
18− * along with this program. If not, see <http://www.gnu.org/licenses/>.
19− */
20−
21−// Self
22−#include "filteroption.h"
23−
24−// libunity-core
25−#include <UnityCore/Filter.h>
26−
27−FilterOption::FilterOption(unity::dash::FilterOption::Ptr unityFilterOption, QObject *parent) :
28− AbstractFilterOption(parent), m_unityFilterOption(nullptr)
29−{
30− setUnityFilterOption(unityFilterOption);
31−}
32−
33−QString FilterOption::id() const
34−{
35− return QString::fromStdString(m_unityFilterOption->id());
36−}
37−
38−QString FilterOption::name() const
39−{
40− return QString::fromStdString(m_unityFilterOption->name());
41−}
42−
43−QString FilterOption::iconHint() const
44−{
45− return QString::fromStdString(m_unityFilterOption->icon_hint());
46−}
47−
48−bool FilterOption::active() const
49−{
50− return m_unityFilterOption->active();
51−}
52−
53−void FilterOption::setActive(bool active)
54−{
55− m_unityFilterOption->active = active;
56−}
57−
58−void FilterOption::setUnityFilterOption(unity::dash::FilterOption::Ptr unityFilterOption)
59−{
60− if (m_unityFilterOption != nullptr) {
61− m_signals.disconnectAll();
62− }
63−
64− m_unityFilterOption = unityFilterOption;
65−
66− /* Property change signals */
67− m_signals << m_unityFilterOption->id.changed.connect(sigc::mem_fun(this, &FilterOption::onIdChanged))
68− << m_unityFilterOption->name.changed.connect(sigc::mem_fun(this, &FilterOption::onNameChanged))
69− << m_unityFilterOption->icon_hint.changed.connect(sigc::mem_fun(this, &FilterOption::onIconHintChanged))
70− << m_unityFilterOption->active.changed.connect(sigc::mem_fun(this, &FilterOption::onActiveChanged));
71−}
72−
73−void FilterOption::onIdChanged(const std::string &id)
74−{
75− Q_EMIT idChanged(QString::fromStdString(id));
76−}
77−
78−void FilterOption::onNameChanged(const std::string &name)
79−{
80− Q_EMIT nameChanged(QString::fromStdString(name));
81−}
82−
83−void FilterOption::onIconHintChanged(const std::string &iconHint)
84−{
85− Q_EMIT iconHintChanged(QString::fromStdString(iconHint));
86−}
87−
88−void FilterOption::onActiveChanged(bool active)
89−{
90− Q_EMIT activeChanged(active);
91−}
plugins/Unity/filteroption.hdeleted−61
@@ -1,61 +0,0 @@
1−/*
2− * Copyright (C) 2011, 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Florian Boucault <florian.boucault@canonical.com>
6− * Pawel Stolowski <pawel.stolowski@canonical.com>
7− *
8− * This program is free software; you can redistribute it and/or modify
9− * it under the terms of the GNU General Public License as published by
10− * the Free Software Foundation; version 3.
11− *
12− * This program is distributed in the hope that it will be useful,
13− * but WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15− * GNU General Public License for more details.
16− *
17− * You should have received a copy of the GNU General Public License
18− * along with this program. If not, see <http://www.gnu.org/licenses/>.
19− */
20−
21−#ifndef FILTEROPTION_H
22−#define FILTEROPTION_H
23−
24−// Local
25−#include "abstractfilteroption.h"
26−#include "signalslist.h"
27−
28−// libunity-core
29−#include <UnityCore/Filter.h>
30−
31−class Q_DECL_EXPORT FilterOption : public AbstractFilterOption
32−{
33− Q_OBJECT
34−
35−public:
36− explicit FilterOption(unity::dash::FilterOption::Ptr unityFilterOption, QObject *parent = nullptr);
37−
38− /* getters */
39− QString id() const override;
40− QString name() const override;
41− QString iconHint() const override;
42− bool active() const override;
43−
44− /* setters */
45− void setActive(bool active) override;
46−
47−private:
48− void onIdChanged(const std::string &id);
49− void onNameChanged(const std::string &name);
50− void onIconHintChanged(const std::string &iconHint);
51− void onActiveChanged(bool active);
52−
53− void setUnityFilterOption(unity::dash::FilterOption::Ptr unityFilterOption);
54− SignalsList m_signals;
55−
56− unity::dash::FilterOption::Ptr m_unityFilterOption;
57−};
58−
59−Q_DECLARE_METATYPE(FilterOption*)
60−
61−#endif // FILTEROPTION_H
plugins/Unity/filters.cppdeleted−165
@@ -1,165 +0,0 @@
1−/*
2− * Copyright (C) 2011, 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Florian Boucault <florian.boucault@canonical.com>
6− * Pawel Stolowski <pawel.stolowski@canonical.com>
7− *
8− * This program is free software; you can redistribute it and/or modify
9− * it under the terms of the GNU General Public License as published by
10− * the Free Software Foundation; version 3.
11− *
12− * This program is distributed in the hope that it will be useful,
13− * but WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15− * GNU General Public License for more details.
16− *
17− * You should have received a copy of the GNU General Public License
18− * along with this program. If not, see <http://www.gnu.org/licenses/>.
19− */
20−
21−// Self
22−#include "filters.h"
23−
24−// Local
25−#include "filter.h"
26−#include "genericoptionsmodel.h"
27−
28−// Qt
29−#include <QDebug>
30−
31−Filters::Filters(unity::dash::Filters::Ptr unityFilters, QObject *parent) :
32− QAbstractListModel(parent), m_unityFilters(unityFilters)
33−{
34− for (unsigned int i=0; i<m_unityFilters->count(); i++) {
35− unity::dash::Filter::Ptr unityFilter = m_unityFilters->FilterAtIndex(i);
36− addFilter(unityFilter, i);
37− }
38− m_unityFilters->filter_added.connect(sigc::mem_fun(this, &Filters::onFilterAdded));
39− m_unityFilters->filter_changed.connect(sigc::mem_fun(this, &Filters::onFilterChanged));
40− m_unityFilters->filter_removed.connect(sigc::mem_fun(this, &Filters::onFilterRemoved));
41−}
42−
43−Filters::~Filters()
44−{
45− while (!m_filters.isEmpty()) {
46− delete m_filters.takeFirst();
47− }
48−}
49−
50−int Filters::rowCount(const QModelIndex& parent) const
51−{
52− Q_UNUSED(parent)
53−
54− return m_unityFilters->count();
55−}
56−
57−QVariant Filters::data(const QModelIndex& index, int role) const
58−{
59− if (!index.isValid()) {
60− return QVariant();
61− }
62−
63− Filter* filter = m_filters.at(index.row());
64− switch (role)
65− {
66− case Filters::RoleId:
67− return filter->id();
68− case Filters::RoleName:
69− case Qt::DisplayRole:
70− return filter->name();
71− case Filters::RoleIconHint:
72− return filter->iconHint();
73− case Filters::RoleRendererName:
74− return filter->rendererName();
75− case Filters::RoleVisible:
76− return filter->visible();
77− case Filters::RoleCollapsed:
78− return filter->collapsed();
79− case Filters::RoleFiltering:
80− return filter->filtering();
81− case Filters::RoleOptions:
82− return QVariant::fromValue(filter->options());
83− default:
84− break;
85− }
86− return QVariant();
87−}
88−
89−QHash<int, QByteArray> Filters::roleNames() const
90−{
91− QHash<int, QByteArray> roles;
92− roles[Filters::RoleId] = "id";
93− roles[Filters::RoleName] = "name";
94− roles[Filters::RoleIconHint] = "iconHint";
95− roles[Filters::RoleRendererName] = "rendererName";
96− roles[Filters::RoleVisible] = "visible";
97− roles[Filters::RoleCollapsed] = "collapsed";
98− roles[Filters::RoleFiltering] = "filtering";
99− roles[Filters::RoleOptions] = "options";
100− return roles;
101−}
102−
103−Filter* Filters::getFilter(const QString& id) const
104−{
105− Q_FOREACH (Filter* filter, m_filters) {
106− if (filter->id() == id) {
107− return filter;
108− }
109− }
110− return nullptr;
111−}
112−
113−void Filters::onFilterAdded(unity::dash::Filter::Ptr unityFilter)
114−{
115− if (unityFilter == nullptr) {
116− return;
117− }
118−
119− int index = m_filters.count();
120− addFilter(unityFilter, index);
121−}
122−
123−void Filters::onFilterChanged(unity::dash::Filter::Ptr unityFilter)
124−{
125− if (unityFilter == nullptr) {
126− return;
127− }
128−
129− QModelIndex filterIndex = index(indexForFilter(unityFilter));
130− Q_EMIT dataChanged(filterIndex, filterIndex);
131−}
132−
133−void Filters::onFilterRemoved(unity::dash::Filter::Ptr unityFilter)
134−{
135− removeFilter(indexForFilter(unityFilter));
136−}
137−
138−void Filters::addFilter(unity::dash::Filter::Ptr unityFilter, int index)
139−{
140− beginInsertRows(QModelIndex(), index, index);
141− Filter* filter = Filter::newFromUnityFilter(unityFilter);
142− if (filter != nullptr) {
143− m_filters.insert(index, filter);
144− }
145− endInsertRows();
146−}
147−
148−void Filters::removeFilter(int index)
149−{
150− beginRemoveRows(QModelIndex(), index, index);
151− Filter* filter = m_filters.takeAt(index);
152− delete filter;
153− endRemoveRows();
154−}
155−
156−int Filters::indexForFilter(unity::dash::Filter::Ptr unityFilter)
157−{
158− for (int index=0; index<m_filters.count(); index++) {
159− if (m_filters[index]->hasUnityFilter(unityFilter)) {
160− return index;
161− }
162− }
163− qWarning() << "Filter" << QString::fromStdString(unityFilter->name()) << "not found in local cache.";
164− return -1;
165−}
plugins/Unity/filters.hdeleted−77
@@ -1,77 +0,0 @@
1−/*
2− * Copyright (C) 2011, 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Florian Boucault <florian.boucault@canonical.com>
6− * Pawel Stolowski <pawel.stolowski@canonical.com>
7− *
8− * This program is free software; you can redistribute it and/or modify
9− * it under the terms of the GNU General Public License as published by
10− * the Free Software Foundation; version 3.
11− *
12− * This program is distributed in the hope that it will be useful,
13− * but WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15− * GNU General Public License for more details.
16− *
17− * You should have received a copy of the GNU General Public License
18− * along with this program. If not, see <http://www.gnu.org/licenses/>.
19− */
20−
21−#ifndef FILTERS_H
22−#define FILTERS_H
23−
24−// Qt
25−#include <QAbstractListModel>
26−#include <QList>
27−
28−// libunity-core
29−#include <UnityCore/Filters.h>
30−#include <UnityCore/Filter.h>
31−
32−class Filter;
33−
34−class Filters : public QAbstractListModel
35−{
36− Q_OBJECT
37−
38− Q_ENUMS(Roles)
39−
40−public:
41− explicit Filters(unity::dash::Filters::Ptr unityFilters, QObject *parent = nullptr);
42− ~Filters();
43−
44− enum Roles {
45− RoleId = Qt::UserRole,
46− RoleName,
47− RoleIconHint,
48− RoleRendererName,
49− RoleVisible,
50− RoleCollapsed,
51− RoleFiltering,
52− RoleOptions
53− };
54−
55− QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
56− int rowCount(const QModelIndex& parent = QModelIndex()) const override;
57− QHash<int, QByteArray> roleNames() const override;
58−
59− Filter* getFilter(const QString& id) const;
60−
61−private:
62− void onFilterAdded(unity::dash::Filter::Ptr unityFilter);
63− void onFilterChanged(unity::dash::Filter::Ptr unityFilter);
64− void onFilterRemoved(unity::dash::Filter::Ptr unityFilter);
65−
66− void addFilter(unity::dash::Filter::Ptr unityFilter, int index);
67− void removeFilter(int index);
68−
69− int indexForFilter(unity::dash::Filter::Ptr unityFilter);
70−
71− unity::dash::Filters::Ptr m_unityFilters;
72− QList<Filter*> m_filters;
73−};
74−
75−Q_DECLARE_METATYPE(Filters*)
76−
77−#endif // FILTERS_H
plugins/Unity/genericoptionsmodel.cppdeleted−187
@@ -1,187 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−// self
21−#include "genericoptionsmodel.h"
22−
23−// local
24−#include "abstractfilteroption.h"
25−#include "showallfilteroption.h"
26−
27−GenericOptionsModel::GenericOptionsModel(bool showAllOption, QObject *parent)
28− : QAbstractListModel(parent)
29−{
30− if (showAllOption)
31− {
32− auto showAll = new ShowAllFilterOption(this);
33− connect(showAll, SIGNAL(activeChanged(bool)), this, SLOT(onOptionChanged()));
34− connect(showAll, SIGNAL(activeChanged(bool)), this, SLOT(onShowAllClicked(bool)));
35− addOption(showAll);
36− }
37−}
38−
39−GenericOptionsModel::~GenericOptionsModel()
40−{
41− Q_FOREACH(auto opt, m_options)
42− {
43− opt->deleteLater();
44− }
45−}
46−
47−QHash<int, QByteArray> GenericOptionsModel::roleNames() const
48−{
49− QHash<int, QByteArray> roles;
50− roles[GenericOptionsModel::RoleId] = "id";
51− roles[GenericOptionsModel::RoleName] = "name";
52− roles[GenericOptionsModel::RoleIconHint] = "iconHint";
53− roles[GenericOptionsModel::RoleActive] = "active";
54− return roles;
55−}
56−
57−QVariant GenericOptionsModel::data(const QModelIndex& index, int role) const
58−{
59− if (!index.isValid()) {
60− return QVariant();
61− }
62−
63− auto filterOption = m_options[index.row()];
64− switch (role)
65− {
66− case GenericOptionsModel::RoleId:
67− return filterOption->id();
68− case GenericOptionsModel::RoleName:
69− case Qt::DisplayRole:
70− return filterOption->name();
71− case GenericOptionsModel::RoleIconHint:
72− return filterOption->iconHint();
73− case GenericOptionsModel::RoleActive:
74− return filterOption->active();
75− default:
76− break;
77− }
78−
79− return QVariant();
80−}
81−
82−int GenericOptionsModel::rowCount(const QModelIndex& /* parent */) const
83−{
84− return m_options.size();
85−}
86−
87−void GenericOptionsModel::setActive(int idx, bool value)
88−{
89− if (idx >= 0 && idx < m_options.size())
90− {
91− m_options[idx]->setActive(value);
92− }
93−}
94−
95−void GenericOptionsModel::setActive(const QString &id, bool value)
96−{
97− Q_FOREACH(auto opt, m_options) {
98− if (opt->id() == id) {
99− opt->setActive(value);
100− break;
101− }
102− }
103−}
104−
105−AbstractFilterOption* GenericOptionsModel::getRawOption(QVector<AbstractFilterOption *>::size_type idx) const
106−{
107− if (idx < m_options.size())
108− {
109− return m_options[idx];
110− }
111− return nullptr;
112−}
113−
114−void GenericOptionsModel::ensureTheOnlyActive(AbstractFilterOption *activeOption)
115−{
116− if (activeOption->active()) {
117− // disable all other options
118− Q_FOREACH(auto opt, m_options) {
119− if (opt != activeOption && opt->active()) {
120− opt->setActive(false);
121− }
122− }
123− }
124−}
125−
126−void GenericOptionsModel::addOption(AbstractFilterOption *option, int index)
127−{
128− if (index >= 0)
129− m_options.insert(index, option);
130− else
131− m_options.append(option);
132−
133− connect(option, SIGNAL(idChanged(const QString &)), this, SLOT(onOptionChanged()));
134− connect(option, SIGNAL(nameChanged(const QString &)), this, SLOT(onOptionChanged()));
135− connect(option, SIGNAL(iconHintChanged(const QString &)), this, SLOT(onOptionChanged()));
136− connect(option, SIGNAL(activeChanged(bool)), this, SLOT(onOptionChanged()));
137− connect(option, SIGNAL(activeChanged(bool)), this, SLOT(onActiveChanged()));
138−}
139−
140−void GenericOptionsModel::removeOption(int index)
141−{
142− m_options[index]->deleteLater();
143− m_options.remove(index);
144−}
145−
146−int GenericOptionsModel::indexOf(const QString &option_id)
147−{
148− int row = 0;
149− Q_FOREACH(auto opt, m_options)
150− {
151− if (opt->id() == option_id)
152− {
153− return row;
154− }
155− ++row;
156− }
157− return -1;
158−}
159−
160−void GenericOptionsModel::onOptionChanged()
161−{
162− AbstractFilterOption *option = dynamic_cast<AbstractFilterOption*>(QObject::sender());
163− if (option)
164− {
165− int idx = indexOf(option->id());
166− if (idx >= 0)
167− {
168− QModelIndex optionIndex = index(idx);
169− Q_EMIT dataChanged(optionIndex, optionIndex);
170− }
171− }
172−}
173−
174−void GenericOptionsModel::onActiveChanged()
175−{
176− AbstractFilterOption *option = dynamic_cast<AbstractFilterOption*>(QObject::sender());
177− if (option)
178− {
179− Q_EMIT activeChanged(option);
180− }
181−}
182−
183−void GenericOptionsModel::onShowAllClicked(bool active)
184−{
185− if (active)
186− Q_EMIT showAllActivated();
187−}
plugins/Unity/genericoptionsmodel.hdeleted−79
@@ -1,79 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#ifndef GENERICOPTIONSMODEL_H
21−#define GENERICOPTIONSMODEL_H
22−
23−// Qt
24−#include <QObject>
25−#include <QAbstractListModel>
26−#include <QHash>
27−#include <QVector>
28−
29−class AbstractFilterOption;
30−
31−class Q_DECL_EXPORT GenericOptionsModel : public QAbstractListModel
32−{
33− Q_OBJECT
34−
35− Q_ENUMS(Roles)
36−
37−public:
38− GenericOptionsModel(bool showAllOption = false, QObject *parent = nullptr);
39− ~GenericOptionsModel();
40−
41− enum Roles {
42− RoleId = Qt::UserRole,
43− RoleName,
44− RoleIconHint,
45− RoleActive
46− };
47−
48− QHash<int, QByteArray> roleNames() const override;
49− QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
50− int rowCount(const QModelIndex& parent = QModelIndex()) const override;
51−
52− Q_INVOKABLE void setActive(int idx, bool value);
53− Q_INVOKABLE void setActive(const QString &id, bool value);
54−
55− AbstractFilterOption* getRawOption(QVector<AbstractFilterOption *>::size_type idx) const;
56−
57−public Q_SLOTS:
58− virtual void ensureTheOnlyActive(AbstractFilterOption *activeOption);
59−
60−Q_SIGNALS:
61− void activeChanged(AbstractFilterOption *option);
62− void showAllActivated();
63−
64−protected Q_SLOTS:
65− void onOptionChanged();
66− void onActiveChanged();
67− void onShowAllClicked(bool active);
68−
69−protected:
70− void addOption(AbstractFilterOption *option, int index = -1);
71− void removeOption(int index);
72− int indexOf(const QString &option_id);
73−
74− QVector<AbstractFilterOption *> m_options;
75−};
76−
77−Q_DECLARE_METATYPE(GenericOptionsModel*)
78−
79−#endif // GENERICOPTIONSMODEL_H
plugins/Unity/moviepreview.cppdeleted−67
@@ -1,67 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−// local
21−#include "moviepreview.h"
22−
23−// Qt
24−#include <QDebug>
25−
26−MoviePreview::MoviePreview(QObject *parent):
27− Preview(parent),
28− m_unityMoviePreview(nullptr)
29−{
30−}
31−
32−QString MoviePreview::year() const
33−{
34− if (m_unityMoviePreview) {
35− return QString::fromStdString(m_unityMoviePreview->year());
36− } else {
37− qWarning() << "Preview not set";
38− }
39− return QString();
40−}
41−
42−float MoviePreview::rating() const
43−{
44− if (m_unityMoviePreview) {
45− return m_unityMoviePreview->rating();
46− } else {
47− qWarning() << "Preview not set";
48− }
49− return 0.0f;
50−}
51−
52−unsigned int MoviePreview::numRatings() const
53−{
54− if (m_unityMoviePreview) {
55− return m_unityMoviePreview->num_ratings();
56− } else {
57− qWarning() << "Preview not set";
58− }
59− return 0;
60−}
61−
62−void MoviePreview::setUnityPreview(unity::dash::Preview::Ptr unityPreview)
63−{
64− m_unityMoviePreview = std::dynamic_pointer_cast<unity::dash::MoviePreview>(unityPreview);
65−
66− Q_EMIT previewChanged();
67−}
plugins/Unity/moviepreview.hdeleted−60
@@ -1,60 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#ifndef MOVIEPREVIEW_H
21−#define MOVIEPREVIEW_H
22−
23−// local
24−#include "preview.h"
25−
26−// Qt
27−#include <QObject>
28−#include <QMetaType>
29−
30−// libunity-core
31−#include <UnityCore/MoviePreview.h>
32−
33−class Q_DECL_EXPORT MoviePreview: public Preview
34−{
35− Q_OBJECT
36−
37− Q_PROPERTY(QString year READ year NOTIFY previewChanged)
38− Q_PROPERTY(float rating READ rating NOTIFY previewChanged)
39− Q_PROPERTY(unsigned int numRatings READ numRatings NOTIFY previewChanged)
40−
41−public:
42− explicit MoviePreview(QObject *parent = 0);
43−
44− QString year() const;
45− float rating() const;
46− unsigned int numRatings() const;
47−
48−Q_SIGNALS:
49− void previewChanged();
50−
51−protected:
52− void setUnityPreview(unity::dash::Preview::Ptr unityPreview) override;
53−
54−private:
55− unity::dash::MoviePreview::Ptr m_unityMoviePreview;
56−};
57−
58−Q_DECLARE_METATYPE(MoviePreview *)
59−
60−#endif
plugins/Unity/multirangefilter.cppdeleted−65
@@ -1,65 +0,0 @@
1−/*
2− * Copyright (C) 2011, 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Florian Boucault <florian.boucault@canonical.com>
6− * Pawel Stolowski <pawel.stolowski@canonical.com>
7− *
8− * This program is free software; you can redistribute it and/or modify
9− * it under the terms of the GNU General Public License as published by
10− * the Free Software Foundation; version 3.
11− *
12− * This program is distributed in the hope that it will be useful,
13− * but WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15− * GNU General Public License for more details.
16− *
17− * You should have received a copy of the GNU General Public License
18− * along with this program. If not, see <http://www.gnu.org/licenses/>.
19− */
20−
21−// Self
22−#include "multirangefilter.h"
23−
24−// local
25−#include "unityoptionsmodel.h"
26−
27−MultiRangeFilter::MultiRangeFilter(QObject *parent) :
28− Filter(parent), m_unityMultiRangeFilter(nullptr), m_options(nullptr)
29−{
30−}
31−
32−GenericOptionsModel* MultiRangeFilter::options() const
33−{
34− return m_options;
35−}
36−
37−void MultiRangeFilter::setUnityFilter(unity::dash::Filter::Ptr filter)
38−{
39− Filter::setUnityFilter(filter);
40− m_unityMultiRangeFilter = std::dynamic_pointer_cast<unity::dash::MultiRangeFilter>(m_unityFilter);
41−
42− onOptionsChanged(m_unityMultiRangeFilter->options);
43−}
44−
45−void MultiRangeFilter::onOptionsChanged(unity::dash::MultiRangeFilter::Options options)
46−{
47− if (m_options != nullptr) {
48− m_signals.disconnectAll();
49− delete m_options;
50− m_options = nullptr;
51− }
52−
53− m_options = new UnityOptionsModel(this, options,
54− m_unityMultiRangeFilter->option_added,
55− m_unityMultiRangeFilter->option_removed,
56− m_unityMultiRangeFilter->show_all_button);
57−
58− connect(m_options, SIGNAL(activeChanged(AbstractFilterOption *)), m_options, SLOT(ensureTheOnlyActive(AbstractFilterOption *)));
59− connect(m_options, SIGNAL(showAllActivated()), this, SLOT(clear()));
60−
61− /* Property change signals */
62− m_signals << m_unityMultiRangeFilter->options.changed.connect(sigc::mem_fun(this, &MultiRangeFilter::onOptionsChanged));
63−
64− Q_EMIT optionsChanged();
65−}
plugins/Unity/multirangefilter.hdeleted−60
@@ -1,60 +0,0 @@
1−/*
2− * Copyright (C) 2011, 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Florian Boucault <florian.boucault@canonical.com>
6− * Pawel Stolowski <pawel.stolowski@canonical.com>
7− *
8− * This program is free software; you can redistribute it and/or modify
9− * it under the terms of the GNU General Public License as published by
10− * the Free Software Foundation; version 3.
11− *
12− * This program is distributed in the hope that it will be useful,
13− * but WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15− * GNU General Public License for more details.
16− *
17− * You should have received a copy of the GNU General Public License
18− * along with this program. If not, see <http://www.gnu.org/licenses/>.
19− */
20−
21−#ifndef MULTIRANGEFILTER_H
22−#define MULTIRANGEFILTER_H
23−
24−// Qt
25−#include <QObject>
26−#include <QMetaType>
27−
28−// libunity-core
29−#include <UnityCore/MultiRangeFilter.h>
30−
31−// Local
32−#include "filter.h"
33−#include "signalslist.h"
34−
35−class GenericOptionsModel;
36−
37−class Q_DECL_EXPORT MultiRangeFilter : public Filter
38−{
39− Q_OBJECT
40−
41−public:
42− explicit MultiRangeFilter(QObject *parent = nullptr);
43−
44− /* getters */
45− GenericOptionsModel* options() const override;
46−
47−protected:
48− void setUnityFilter(unity::dash::Filter::Ptr filter) override;
49−
50−private:
51− unity::dash::MultiRangeFilter::Ptr m_unityMultiRangeFilter;
52− SignalsList m_signals;
53− GenericOptionsModel* m_options;
54−
55− void onOptionsChanged(unity::dash::MultiRangeFilter::Options);
56−};
57−
58−Q_DECLARE_METATYPE(MultiRangeFilter*)
59−
60−#endif // MULTIRANGEFILTER_H
plugins/Unity/musicpreview.cppdeleted−54
@@ -1,54 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#include "musicpreview.h"
21−#include <QDebug>
22−
23−// dee-qt
24−#include "deelistmodel.h"
25−
26−MusicPreview::MusicPreview(QObject *parent):
27− Preview(parent),
28− m_unityMusicPreview(nullptr)
29−{
30− m_tracks = new DeeListModel(this);
31−}
32−
33−void MusicPreview::setUnityPreview(unity::dash::Preview::Ptr unityPreview)
34−{
35− m_unityMusicPreview = std::dynamic_pointer_cast<unity::dash::MusicPreview>(unityPreview);
36− m_tracks->setModel(m_unityMusicPreview->GetTracksModel()->model());
37− m_unityMusicPreview->GetTracksModel()->model.changed.connect(sigc::mem_fun(this, &MusicPreview::onTracksModelChanged));
38−
39− Q_EMIT previewChanged();
40− Q_EMIT tracksChanged();
41−}
42−
43−DeeListModel* MusicPreview::tracks() const
44−{
45− if (m_unityMusicPreview == nullptr) {
46− qWarning() << "Preview not set";
47− }
48− return m_tracks;
49−}
50−
51−void MusicPreview::onTracksModelChanged(unity::glib::Object<DeeModel> /* model */)
52−{
53− m_tracks->setModel(m_unityMusicPreview->GetTracksModel()->model());
54−}
plugins/Unity/musicpreview.hdeleted−62
@@ -1,62 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#ifndef MUSICPREVIEW_H
21−#define MUSICPREVIEW_H
22−
23−// local
24−#include "preview.h"
25−
26−// Qt
27−#include <QObject>
28−#include <QMetaType>
29−
30−// libunity-core
31−#include <UnityCore/MusicPreview.h>
32−
33−class DeeListModel;
34−
35−class Q_DECL_EXPORT MusicPreview: public Preview
36−{
37− Q_OBJECT
38−
39− Q_PROPERTY(DeeListModel* tracks READ tracks NOTIFY tracksChanged)
40−
41−public:
42− explicit MusicPreview(QObject *parent = 0);
43−
44− DeeListModel* tracks() const;
45−
46−Q_SIGNALS:
47− void tracksChanged();
48−
49−protected:
50− void setUnityPreview(unity::dash::Preview::Ptr unityPreview) override;
51−
52−private Q_SLOTS:
53− void onTracksModelChanged(unity::glib::Object<DeeModel> model);
54−
55−private:
56− unity::dash::MusicPreview::Ptr m_unityMusicPreview;
57− DeeListModel *m_tracks;
58−};
59−
60−Q_DECLARE_METATYPE(MusicPreview *)
61−
62−#endif
plugins/Unity/plugin.cppdeleted−74
@@ -1,74 +0,0 @@
1−/*
2− * Copyright (C) 2012 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− *
16− * Author: Michał Sawicz <michal.sawicz@canonical.com>
17− */
18−
19−// Qt
20−#include <QDBusConnection>
21−#include <QQmlContext>
22−#include <qqml.h>
23−
24−// self
25−#include "plugin.h"
26−
27−// local
28−#include "preview.h"
29−#include "previewaction.h"
30−#include "previewinfohint.h"
31−#include "socialpreviewcomment.h"
32−#include "scope.h"
33−#include "scopes.h"
34−#include "categories.h"
35−#include "categoryresults.h"
36−#include "bottombarvisibilitycommunicatorshell.h"
37−#include "genericoptionsmodel.h"
38−#include "result.h"
39−
40−// libqtdee
41−#include "deelistmodel.h"
42−
43−static const char* BOTTOM_BAR_VISIBILITY_COMMUNICATOR_DBUS_PATH = "/BottomBarVisibilityCommunicator";
44−static const char* DBUS_SERVICE = "com.canonical.Shell.BottomBarVisibilityCommunicator";
45−
46−void UnityPlugin::registerTypes(const char *uri)
47−{
48− Q_ASSERT(uri == QLatin1String("Unity"));
49− qmlRegisterUncreatableType<Preview>(uri, 0, 1, "Preview", "Can't create Preview object in QML.");
50− qmlRegisterUncreatableType<PreviewAction>(uri, 0, 1, "PreviewAction", "Can't create PreviewAction object in QML.");
51− qmlRegisterUncreatableType<PreviewInfoHint>(uri, 0, 1, "PreviewInfoHint", "Can't create PreviewInfoHint object in QML.");
52− qmlRegisterUncreatableType<SocialPreviewComment>(uri, 0, 1, "SocialPreviewComment", "Can't create SocialPreviewComment object in QML.");
53− qmlRegisterUncreatableType<GenericOptionsModel>(uri, 0, 1, "GenericOptionsModel", "Can't create options model in QML.");
54− qmlRegisterUncreatableType<Result>(uri, 0, 1, "Result", "Can't create result object in QML.");
55− qmlRegisterType<Scope>(uri, 0, 1, "Scope");
56− qmlRegisterType<Scopes>(uri, 0, 1, "Scopes");
57− qmlRegisterType<Categories>(uri, 0, 1, "Categories");
58− qmlRegisterUncreatableType<CategoryResults>(uri, 0, 1, "CategoryResults", "Can't create new Category Results in QML. Get them from Categories instance.");
59− qmlRegisterType<DeeListModel>(uri, 0, 1, "DeeListModel");
60− qmlRegisterUncreatableType<BottomBarVisibilityCommunicatorShell>(uri, 0, 1, "BottomBarVisibilityCommunicatorShell", "Can't create BottomBarVisibilityCommunicatorShell");
61−}
62−
63−void UnityPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
64−{
65− QQmlExtensionPlugin::initializeEngine(engine, uri);
66−#ifndef GLIB_VERSION_2_36
67− g_type_init();
68−#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);
74−}
plugins/Unity/preview.cppdeleted−199
@@ -1,199 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−// local
21−#include "preview.h"
22−#include "previewaction.h"
23−#include "previewinfohint.h"
24−#include "genericpreview.h"
25−#include "applicationpreview.h"
26−#include "moviepreview.h"
27−#include "musicpreview.h"
28−#include "socialpreview.h"
29−#include "iconutils.h"
30−#include "variantutils.h"
31−
32−// Qt
33−#include <QDebug>
34−#include <QtAlgorithms>
35−
36−#include <UnityCore/GenericPreview.h>
37−#include <UnityCore/ApplicationPreview.h>
38−#include <UnityCore/MoviePreview.h>
39−#include <UnityCore/MusicPreview.h>
40−#include <UnityCore/SocialPreview.h>
41−
42−#include <UnityCore/GLibWrapper.h>
43−
44−Preview::Preview(QObject *parent):
45− QObject(parent),
46− m_unityPreview(nullptr),
47− m_result(new Result(this))
48−{
49−}
50−
51−QString Preview::rendererName() const
52−{
53− if (m_unityPreview) {
54− return QString::fromStdString(m_unityPreview->renderer_name());
55− } else {
56− qWarning() << "Preview not set";
57− }
58− return QString();
59−}
60−
61−QString Preview::title() const
62−{
63− if (m_unityPreview) {
64− return QString::fromStdString(m_unityPreview->title());
65− } else {
66− qWarning() << "Preview not set";
67− }
68− return QString();
69−}
70−
71−QString Preview::subtitle () const
72−{
73− if (m_unityPreview) {
74− return QString::fromStdString(m_unityPreview->subtitle());
75− } else {
76− qWarning() << "Preview not set";
77− }
78− return QString();
79−}
80−
81−QString Preview::description() const
82−{
83− if (m_unityPreview) {
84− return QString::fromStdString(m_unityPreview->description());
85− } else {
86− qWarning() << "Preview not set";
87− }
88− return QString();
89−}
90−
91−QVariant Preview::actions()
92−{
93− return QVariant::fromValue(m_actions);
94−}
95−
96−QVariant Preview::infoHints()
97−{
98− return QVariant::fromValue(m_infoHints);
99−}
100−
101−QVariantMap Preview::infoHintsHash() const
102−{
103− return m_infoHintsHash;
104−}
105−
106−QString Preview::image() const
107−{
108− if (m_unityPreview) {
109− if (m_unityPreview->image() != nullptr) {
110− auto giconString = g_icon_to_string(m_unityPreview->image());
111− QString result(gIconToDeclarativeImageProviderString(QString::fromUtf8(giconString)));
112− g_free(giconString);
113− return result;
114− } else {
115− QString sourceMedia(QString::fromStdString(m_unityPreview->image_source_uri()));
116− QString thumbnailUri(uriToThumbnailerProviderString(sourceMedia, m_result->mimeType(), m_result->metadata().toHash()));
117− if (!thumbnailUri.isNull()) return thumbnailUri;
118− }
119− } else {
120− qWarning() << "Preview not set";
121− }
122− return QString::null;
123−}
124−
125−QVariant Preview::result() const
126−{
127− return QVariant::fromValue(m_result);
128−}
129−
130−Preview* Preview::newFromUnityPreview(unity::dash::Preview::Ptr unityPreview)
131−{
132− Preview* preview = nullptr;
133−
134− if (dynamic_cast<unity::dash::GenericPreview *>(unityPreview.get()) != nullptr) {
135− preview = new GenericPreview();
136− } else if (dynamic_cast<unity::dash::MusicPreview *>(unityPreview.get()) != nullptr) {
137− preview = new MusicPreview();
138− } else if (dynamic_cast<unity::dash::MoviePreview *>(unityPreview.get()) != nullptr) {
139− preview = new MoviePreview();
140− } else if (dynamic_cast<unity::dash::ApplicationPreview *>(unityPreview.get()) != nullptr) {
141− preview = new ApplicationPreview();
142− } else if (dynamic_cast<unity::dash::SocialPreview *>(unityPreview.get()) != nullptr) {
143− preview = new SocialPreview();
144− } else {
145− qWarning() << "Unknown preview type: " << typeid(*unityPreview).name();
146− preview = new GenericPreview();
147− }
148−
149− preview->setUnityPreviewBase(unityPreview);
150− preview->setUnityPreview(unityPreview);
151−
152− return preview;
153−}
154−
155−void Preview::setUnityPreviewBase(unity::dash::Preview::Ptr unityPreview)
156−{
157− m_unityPreview = unityPreview;
158− m_result->setPreview(unityPreview);
159−
160− qDeleteAll(m_infoHints);
161− m_infoHints.clear();
162− m_infoHintsHash.clear();
163− qDeleteAll(m_actions);
164− m_actions.clear();
165−
166− for (auto unityInfoHint: m_unityPreview->GetInfoHints()) {
167− auto hint = new PreviewInfoHint(this);
168− hint->setUnityInfoHint(unityInfoHint);
169− m_infoHints.append(hint);
170− m_infoHintsHash[hint->id()] = QVariant::fromValue(hint);
171− }
172−
173− for (auto unityAction: m_unityPreview->GetActions()) {
174− auto action = new PreviewAction(this);
175− action->setUnityAction(unityAction);
176− m_actions.append(action);
177− }
178−}
179−
180−void Preview::setUnityPreview(unity::dash::Preview::Ptr /* unityPreview */)
181−{
182− // default implementation does nothing
183−}
184−
185−void Preview::execute(const QString& actionId, const QHash<QString, QVariant>& hints)
186−{
187− if (m_unityPreview) {
188− auto unityHints = convertToHintsMap(hints);
189− m_actionCancellable.Renew();
190− m_unityPreview->PerformAction(actionId.toStdString(), unityHints, nullptr, m_actionCancellable);
191− } else {
192− qWarning() << "Preview not set";
193− }
194−}
195−
196−void Preview::cancelAction()
197−{
198− m_actionCancellable.Cancel();
199−}
plugins/Unity/preview.hdeleted−89
@@ -1,89 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#ifndef PREVIEW_H
21−#define PREVIEW_H
22−
23−// Qt
24−#include <QObject>
25−#include <QString>
26−#include <QMetaType>
27−#include <QList>
28−#include <QVariantMap>
29−
30−// libunity-core
31−#include <UnityCore/Preview.h>
32−
33−// local
34−#include "result.h"
35−#include "previewaction.h"
36−#include <UnityCore/GLibWrapper.h>
37−
38−class Q_DECL_EXPORT Preview : public QObject
39−{
40− Q_OBJECT
41−
42− Q_PROPERTY(QString rendererName READ rendererName NOTIFY previewChanged)
43− Q_PROPERTY(QString title READ title NOTIFY previewChanged)
44− Q_PROPERTY(QString subtitle READ subtitle NOTIFY previewChanged)
45− Q_PROPERTY(QString description READ description NOTIFY previewChanged)
46− Q_PROPERTY(QVariant actions READ actions NOTIFY previewChanged)
47− Q_PROPERTY(QVariant infoHints READ infoHints NOTIFY previewChanged)
48− Q_PROPERTY(QVariantMap infoMap READ infoHintsHash NOTIFY previewChanged)
49− Q_PROPERTY(QString image READ image NOTIFY previewChanged)
50− Q_PROPERTY(QVariant result READ result NOTIFY previewChanged)
51−
52−public:
53− explicit Preview(QObject *parent = 0);
54− static Preview* newFromUnityPreview(unity::dash::Preview::Ptr unityPreview);
55−
56− QString rendererName() const;
57− QString title() const;
58− QString subtitle() const;
59− QString description() const;
60− QVariant actions();
61− QVariant infoHints();
62− QVariantMap infoHintsHash() const;
63− QString image() const;
64− QVariant result() const;
65−
66− Q_INVOKABLE void execute(const QString& actionId, const QHash<QString, QVariant>& hints);
67− Q_INVOKABLE void cancelAction();
68−
69−Q_SIGNALS:
70− void previewChanged();
71−
72−protected:
73− virtual void setUnityPreview(unity::dash::Preview::Ptr unityPreview);
74−
75− unity::dash::Preview::Ptr m_unityPreview;
76− Result* m_result;
77−
78−private:
79− void setUnityPreviewBase(unity::dash::Preview::Ptr unityPreview);
80−
81− QList<QObject *> m_actions;
82− QList<QObject *> m_infoHints;
83− QVariantMap m_infoHintsHash;
84− unity::glib::Cancellable m_actionCancellable;
85−};
86−
87−Q_DECLARE_METATYPE(Preview *)
88−
89−#endif
plugins/Unity/previewaction.cppdeleted−75
@@ -1,75 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#include "previewaction.h"
21−
22−PreviewAction::PreviewAction(QObject *parent)
23− : QObject(parent),
24− m_unityAction(nullptr)
25−{
26−}
27−
28−void PreviewAction::setUnityAction(unity::dash::Preview::ActionPtr unityAction)
29−{
30− m_unityAction = unityAction;
31−
32− Q_EMIT previewActionChanged();
33−}
34−
35−QString PreviewAction::id() const
36−{
37− if (m_unityAction)
38− return QString::fromStdString(m_unityAction->id);
39− return QString();
40−}
41−
42−QString PreviewAction::displayName() const
43−{
44− if (m_unityAction)
45− return QString::fromStdString(m_unityAction->display_name);
46− return QString();
47−}
48−
49−QString PreviewAction::iconHint() const
50−{
51− if (m_unityAction)
52− return QString::fromStdString(m_unityAction->icon_hint);
53− return QString();
54−}
55−
56−QString PreviewAction::extraText() const
57−{
58− if (m_unityAction)
59− return QString::fromStdString(m_unityAction->extra_text);
60− return QString();
61−}
62−
63−QString PreviewAction::activationUri() const
64−{
65− if (m_unityAction)
66− return QString::fromStdString(m_unityAction->activation_uri);
67− return QString();
68−}
69−
70−LayoutHint PreviewAction::layoutHint() const
71−{
72− if (m_unityAction)
73− return static_cast<LayoutHint>(m_unityAction->layout_hint);
74− return LayoutHint::None;
75−}
plugins/Unity/previewaction.hdeleted−71
@@ -1,71 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#ifndef PREVIEWACTION_H
21−#define PREVIEWACTION_H
22−
23−// Qt
24−#include <QObject>
25−#include <QList>
26−
27−// libuinity-core
28−#include <UnityCore/Preview.h>
29−
30−enum LayoutHint // keep in sync with unty::dash::LayoutHint
31−{
32− None,
33− Left,
34− Right,
35− Top,
36− Bottom
37−};
38−
39−class Q_DECL_EXPORT PreviewAction : public QObject
40−{
41− Q_OBJECT
42−
43− Q_PROPERTY(QString id READ id NOTIFY previewActionChanged)
44− Q_PROPERTY(QString displayName READ displayName NOTIFY previewActionChanged)
45− Q_PROPERTY(QString iconHint READ iconHint NOTIFY previewActionChanged)
46− Q_PROPERTY(QString extraText READ extraText NOTIFY previewActionChanged)
47− Q_PROPERTY(QString activationUri READ activationUri NOTIFY previewActionChanged)
48− Q_PROPERTY(LayoutHint layoutHint READ layoutHint NOTIFY previewActionChanged)
49−
50−public:
51− explicit PreviewAction(QObject *parent = 0);
52− void setUnityAction(unity::dash::Preview::ActionPtr unityAction);
53−
54− QString id() const;
55− QString displayName() const;
56− QString iconHint() const;
57− QString extraText() const;
58− QString activationUri() const;
59− LayoutHint layoutHint() const;
60−
61−Q_SIGNALS:
62− void previewActionChanged();
63−
64−private:
65− unity::dash::Preview::ActionPtr m_unityAction;
66−};
67−
68−Q_DECLARE_METATYPE(PreviewAction *)
69−Q_DECLARE_METATYPE(LayoutHint)
70−
71−#endif
plugins/Unity/previewinfohint.cppdeleted−67
@@ -1,67 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#include <deelistmodel.h>
21−// local
22−#include "previewinfohint.h"
23−
24−PreviewInfoHint::PreviewInfoHint(QObject *parent):
25− QObject(parent),
26− m_unityInfoHint(nullptr)
27−{
28−}
29−
30−void PreviewInfoHint::setUnityInfoHint(unity::dash::Preview::InfoHintPtr unityInfoHint)
31−{
32− m_unityInfoHint = unityInfoHint;
33−
34− Q_EMIT previewInfoHintChanged();
35−}
36−
37−QString PreviewInfoHint::id() const
38−{
39− if (m_unityInfoHint) {
40− return QString::fromStdString(m_unityInfoHint->id);
41− }
42− return QString();
43−}
44−
45−QString PreviewInfoHint::displayName() const
46−{
47− if (m_unityInfoHint) {
48− return QString::fromStdString(m_unityInfoHint->display_name);
49− }
50− return QString();
51−}
52−
53−QString PreviewInfoHint::iconHint() const
54−{
55− if (m_unityInfoHint) {
56− return QString::fromStdString(m_unityInfoHint->icon_hint);
57− }
58− return QString();
59−}
60−
61−QVariant PreviewInfoHint::value() const
62−{
63− if (m_unityInfoHint) {
64− return DeeListModel::VariantForData(m_unityInfoHint->value);
65− }
66− return QVariant();
67−}
plugins/Unity/previewinfohint.hdeleted−58
@@ -1,58 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#ifndef PREVIEWINFOHINT_H
21−#define PREVIEWINFOHINT_H
22−
23−// Qt
24−#include <QObject>
25−#include <QString>
26−#include <QVariant>
27−
28−// libunity-core
29−#include <UnityCore/Preview.h>
30−
31−class PreviewInfoHint : public QObject
32−{
33− Q_OBJECT
34−
35− Q_PROPERTY(QString id READ id NOTIFY previewInfoHintChanged)
36− Q_PROPERTY(QString displayName READ displayName NOTIFY previewInfoHintChanged)
37− Q_PROPERTY(QString iconHint READ iconHint NOTIFY previewInfoHintChanged)
38− Q_PROPERTY(QVariant value READ value NOTIFY previewInfoHintChanged)
39−
40−public:
41− explicit PreviewInfoHint(QObject *parent = 0);
42− void setUnityInfoHint(unity::dash::Preview::InfoHintPtr unityInfoHint);
43−
44− QString id() const;
45− QString displayName() const;
46− QString iconHint() const;
47− QVariant value() const;
48−
49−Q_SIGNALS:
50− void previewInfoHintChanged();
51−
52−private:
53− unity::dash::Preview::InfoHintPtr m_unityInfoHint;
54−};
55−
56−Q_DECLARE_METATYPE(PreviewInfoHint *)
57−
58−#endif
plugins/Unity/qmldirdeleted−3
@@ -1,3 +0,0 @@
1−module Unity
2−plugin Unity-qml
3−typeinfo plugin.qmltypes
plugins/Unity/radiooptionfilter.cppdeleted−61
@@ -1,61 +0,0 @@
1−/*
2− * Copyright (C) 2011, 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Florian Boucault <florian.boucault@canonical.com>
6− * Pawel Stolowski <pawel.stolowski@canonical.com>
7− *
8− * This program is free software; you can redistribute it and/or modify
9− * it under the terms of the GNU General Public License as published by
10− * the Free Software Foundation; version 3.
11− *
12− * This program is distributed in the hope that it will be useful,
13− * but WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15− * GNU General Public License for more details.
16− *
17− * You should have received a copy of the GNU General Public License
18− * along with this program. If not, see <http://www.gnu.org/licenses/>.
19− */
20−
21−// Self
22−#include "radiooptionfilter.h"
23−
24−// local
25−#include "unityoptionsmodel.h"
26−
27−RadioOptionFilter::RadioOptionFilter(QObject *parent) :
28− Filter(parent), m_unityRadioOptionFilter(nullptr), m_options(nullptr)
29−{
30−}
31−
32−GenericOptionsModel* RadioOptionFilter::options() const
33−{
34− return m_options;
35−}
36−
37−void RadioOptionFilter::setUnityFilter(unity::dash::Filter::Ptr filter)
38−{
39− Filter::setUnityFilter(filter);
40− m_unityRadioOptionFilter = std::dynamic_pointer_cast<unity::dash::RadioOptionFilter>(m_unityFilter);
41−
42− onOptionsChanged(m_unityRadioOptionFilter->options);
43−}
44−
45−void RadioOptionFilter::onOptionsChanged(unity::dash::RadioOptionFilter::RadioOptions)
46−{
47− if (m_options != nullptr) {
48− m_signals.disconnectAll();
49− delete m_options;
50− m_options = nullptr;
51− }
52− m_options = new UnityOptionsModel(this, m_unityRadioOptionFilter->options,
53− m_unityRadioOptionFilter->option_added,
54− m_unityRadioOptionFilter->option_removed,
55− m_unityRadioOptionFilter->show_all_button);
56− connect(m_options, SIGNAL(showAllActivated()), this, SLOT(clear()));
57−
58− m_signals << m_unityRadioOptionFilter->options.changed.connect(sigc::mem_fun(this, &RadioOptionFilter::onOptionsChanged));
59−
60− Q_EMIT optionsChanged();
61−}
plugins/Unity/radiooptionfilter.hdeleted−59
@@ -1,59 +0,0 @@
1−/*
2− * Copyright (C) 2011, 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Florian Boucault <florian.boucault@canonical.com>
6− * Pawel Stolowski <pawel.stolowski@canonical.com>
7− *
8− * This program is free software; you can redistribute it and/or modify
9− * it under the terms of the GNU General Public License as published by
10− * the Free Software Foundation; version 3.
11− *
12− * This program is distributed in the hope that it will be useful,
13− * but WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15− * GNU General Public License for more details.
16− *
17− * You should have received a copy of the GNU General Public License
18− * along with this program. If not, see <http://www.gnu.org/licenses/>.
19− */
20−
21−#ifndef RADIOOPTIONFILTER_H
22−#define RADIOOPTIONFILTER_H
23−
24−// Qt
25−#include <QObject>
26−#include <QMetaType>
27−
28−// libunity-core
29−#include <UnityCore/RadioOptionFilter.h>
30−
31−// Local
32−#include "filter.h"
33−#include "filteroption.h"
34−#include "signalslist.h"
35−
36−class Q_DECL_EXPORT RadioOptionFilter : public Filter
37−{
38− Q_OBJECT
39−
40−public:
41− explicit RadioOptionFilter(QObject *parent = nullptr);
42−
43− /* getters */
44− GenericOptionsModel* options() const override;
45−
46−protected:
47− void setUnityFilter(unity::dash::Filter::Ptr filter) override;
48−
49−private:
50− unity::dash::RadioOptionFilter::Ptr m_unityRadioOptionFilter;
51− GenericOptionsModel* m_options;
52− SignalsList m_signals;
53−
54− void onOptionsChanged(unity::dash::RadioOptionFilter::RadioOptions);
55−};
56−
57−Q_DECLARE_METATYPE(RadioOptionFilter*)
58−
59−#endif // RADIOOPTIONFILTER_H
plugins/Unity/ratingfilteroption.cppdeleted−62
@@ -1,62 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−// self
21−#include "ratingfilteroption.h"
22−
23−RatingFilterOption::RatingFilterOption(const QString &id, float value, QObject *parent) :
24− AbstractFilterOption(parent),
25− m_active(false),
26− m_id(id),
27− m_value(value)
28−{
29−}
30−
31−QString RatingFilterOption::id() const
32−{
33− return m_id;
34−}
35−
36−QString RatingFilterOption::name() const
37−{
38− return QString::Null();
39−}
40−
41−QString RatingFilterOption::iconHint() const
42−{
43− return QString::Null();
44−}
45−
46−float RatingFilterOption::value() const
47−{
48− return m_value;
49−}
50−
51−bool RatingFilterOption::active() const
52−{
53− return m_active;
54−}
55−
56−void RatingFilterOption::setActive(bool active)
57−{
58− if (active != m_active) {
59− m_active = active;
60− Q_EMIT activeChanged(m_active);
61− }
62−}
plugins/Unity/ratingfilteroption.hdeleted−53
@@ -1,53 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#ifndef RATINGFILTEROPTION_H
21−#define RATINGFILTEROPTION_H
22−
23−// local
24−#include "abstractfilteroption.h"
25−
26−class Q_DECL_EXPORT RatingFilterOption : public AbstractFilterOption
27−{
28− Q_OBJECT
29−
30− Q_PROPERTY(float value READ value CONSTANT)
31−
32−public:
33− explicit RatingFilterOption(const QString &id, float ratingValue, QObject *parent = nullptr);
34−
35− /* getters */
36− QString id() const override;
37− QString name() const override;
38− QString iconHint() const override;
39− bool active() const override;
40− float value() const;
41−
42− /* setters */
43− void setActive(bool active) override;
44−
45−private:
46− bool m_active;
47− QString m_id;
48− float m_value;
49−};
50−
51−Q_DECLARE_METATYPE(RatingFilterOption*)
52−
53−#endif // RATINGFILTEROPTION_H
plugins/Unity/ratingsfilter.cppdeleted−73
@@ -1,73 +0,0 @@
1−/*
2− * Copyright (C) 2011, 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Florian Boucault <florian.boucault@canonical.com>
6− * Pawel Stolowski <pawel.stolowski@canonical.com>
7− *
8− * This program is free software; you can redistribute it and/or modify
9− * it under the terms of the GNU General Public License as published by
10− * the Free Software Foundation; version 3.
11− *
12− * This program is distributed in the hope that it will be useful,
13− * but WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15− * GNU General Public License for more details.
16− *
17− * You should have received a copy of the GNU General Public License
18− * along with this program. If not, see <http://www.gnu.org/licenses/>.
19− */
20−
21−// Self
22−#include "ratingsfilter.h"
23−
24−// local
25−#include "ratingfilteroption.h"
26−#include "ratingoptionsmodel.h"
27−
28−RatingsFilter::RatingsFilter(QObject *parent) :
29− Filter(parent),
30− m_unityRatingsFilter(nullptr),
31− m_options(nullptr)
32−{
33−}
34−
35−GenericOptionsModel* RatingsFilter::options() const
36−{
37− return m_options;
38−}
39−
40−float RatingsFilter::rating() const
41−{
42− if (m_unityRatingsFilter)
43− {
44− return m_unityRatingsFilter->rating;
45− }
46− return 0.0f;
47−}
48−
49−void RatingsFilter::setUnityFilter(unity::dash::Filter::Ptr filter)
50−{
51− Filter::setUnityFilter(filter);
52− m_unityRatingsFilter = std::dynamic_pointer_cast<unity::dash::RatingsFilter>(m_unityFilter);
53−
54− delete m_options;
55−
56− m_options = new RatingOptionsModel(m_unityRatingsFilter->show_all_button, this);
57− connect(m_options, SIGNAL(activeChanged(AbstractFilterOption *)), m_options, SLOT(ensureTheOnlyActive(AbstractFilterOption *)));
58− connect(m_options, SIGNAL(activeChanged(AbstractFilterOption *)), this, SLOT(onActiveChanged(AbstractFilterOption *)));
59− connect(m_options, SIGNAL(showAllActivated()), this, SLOT(clear()));
60−
61− Q_EMIT optionsChanged();
62−}
63−
64−void RatingsFilter::onActiveChanged(AbstractFilterOption *option)
65−{
66− RatingFilterOption *ratingOption = dynamic_cast<RatingFilterOption*>(option);
67− if (ratingOption != nullptr)
68− {
69− const float val = ratingOption->active() ? ratingOption->value() : 0.0f;
70− m_unityRatingsFilter->rating = val;
71− Q_EMIT ratingChanged(val);
72− }
73−}
plugins/Unity/ratingsfilter.hdeleted−66
@@ -1,66 +0,0 @@
1−/*
2− * Copyright (C) 2011, 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Florian Boucault <florian.boucault@canonical.com>
6− * Pawel Stolowski <pawel.stolowski@canonical.com>
7− *
8− * This program is free software; you can redistribute it and/or modify
9− * it under the terms of the GNU General Public License as published by
10− * the Free Software Foundation; version 3.
11− *
12− * This program is distributed in the hope that it will be useful,
13− * but WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15− * GNU General Public License for more details.
16− *
17− * You should have received a copy of the GNU General Public License
18− * along with this program. If not, see <http://www.gnu.org/licenses/>.
19− */
20−
21−#ifndef RATINGSFILTER_H
22−#define RATINGSFILTER_H
23−
24−// Qt
25−#include <QObject>
26−#include <QMetaType>
27−
28−// libunity-core
29−#include <UnityCore/RatingsFilter.h>
30−
31−// Local
32−#include "filter.h"
33−
34−class GenericOptionsModel;
35−class AbstractFilterOption;
36−
37−class Q_DECL_EXPORT RatingsFilter : public Filter
38−{
39− Q_OBJECT
40−
41− Q_PROPERTY(float rating READ rating NOTIFY ratingChanged)
42−
43−public:
44− explicit RatingsFilter(QObject *parent = nullptr);
45−
46− /* getters */
47− GenericOptionsModel* options() const override;
48− float rating() const;
49−
50−Q_SIGNALS:
51− void ratingChanged(float);
52−
53−protected:
54− void setUnityFilter(unity::dash::Filter::Ptr filter) override;
55−
56−protected Q_SLOTS:
57− void onActiveChanged(AbstractFilterOption *option);
58−
59−private:
60− unity::dash::RatingsFilter::Ptr m_unityRatingsFilter;
61− GenericOptionsModel *m_options;
62−};
63−
64−Q_DECLARE_METATYPE(RatingsFilter*)
65−
66−#endif // RATINGSFILTER_H
plugins/Unity/result.cppdeleted−82
@@ -1,82 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#include "result.h"
21−#include "variantutils.h"
22−
23−Result::Result(QObject *parent) :
24− QObject(parent)
25−{
26−}
27−
28−Result::Result(unity::dash::Preview::Ptr preview, QObject *parent) :
29− QObject(parent),
30− m_preview(preview)
31−{
32−}
33−
34−void Result::setPreview(unity::dash::Preview::Ptr preview)
35−{
36− m_preview = preview;
37−}
38−
39−QString Result::uri() const
40−{
41− return m_preview != nullptr ? QString::fromStdString(m_preview->preview_result.uri) : QString::null;
42−}
43−
44−QString Result::iconHint() const
45−{
46− return m_preview != nullptr ? QString::fromStdString(m_preview->preview_result.icon_hint) : QString::null;
47−}
48−
49−unsigned Result::categoryIndex() const
50−{
51− return m_preview != nullptr ? m_preview->preview_result.category_index : 0;
52−}
53−
54−unsigned Result::resultType() const
55−{
56− return m_preview != nullptr ? m_preview->preview_result.result_type : 0;
57−}
58−
59−QString Result::mimeType() const
60−{
61− return m_preview != nullptr ? QString::fromStdString(m_preview->preview_result.mimetype) : QString::null;
62−}
63−
64−QString Result::title() const
65−{
66− return m_preview != nullptr ? QString::fromStdString(m_preview->preview_result.name) : QString::null;
67−}
68−
69−QString Result::comment() const
70−{
71− return m_preview != nullptr ? QString::fromStdString(m_preview->preview_result.comment) : QString::null;
72−}
73−
74−QString Result::dndUri() const
75−{
76− return m_preview != nullptr ? QString::fromStdString(m_preview->preview_result.dnd_uri) : QString::null;
77−}
78−
79−QVariant Result::metadata() const
80−{
81− return m_preview != nullptr ? convertToQVariantHash(m_preview->preview_result.hints) : QVariant();
82−}
plugins/Unity/result.hdeleted−69
@@ -1,69 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#ifndef RESULT_H
21−#define RESULT_H
22−
23−// Qt
24−#include <QObject>
25−#include <QVariant>
26−
27−// libunity-core
28−#include <UnityCore/Preview.h>
29−
30−class Q_DECL_EXPORT Result : public QObject
31−{
32− Q_OBJECT
33−
34− Q_PROPERTY(QString uri READ uri CONSTANT)
35− Q_PROPERTY(QString iconHint READ iconHint CONSTANT)
36− Q_PROPERTY(unsigned categoryIndex READ categoryIndex CONSTANT)
37− Q_PROPERTY(unsigned resultType READ resultType CONSTANT)
38− Q_PROPERTY(QString mimeType READ mimeType CONSTANT)
39− Q_PROPERTY(QString title READ title CONSTANT)
40− Q_PROPERTY(QString comment READ comment CONSTANT)
41− Q_PROPERTY(QString dndUri READ dndUri CONSTANT)
42− Q_PROPERTY(QVariant metadata READ metadata CONSTANT)
43−
44−public:
45− Result(QObject *parent = nullptr);
46− Result(unity::dash::Preview::Ptr preview, QObject *parent = nullptr);
47−
48− void setPreview(unity::dash::Preview::Ptr preview);
49−
50− QString uri() const;
51− QString iconHint() const;
52− unsigned categoryIndex() const;
53− unsigned resultType() const;
54− QString mimeType() const;
55− QString title() const;
56− QString comment() const;
57− QString dndUri() const;
58− QVariant metadata() const;
59−
60−private:
61− /* Keep reference to the original preview to access result attributes via it, rather than keeping copies of them;
62− this will save us a bit on copying, especially as UI is mostly interested in just uri.
63− */
64− unity::dash::Preview::Ptr m_preview;
65−};
66−
67−Q_DECLARE_METATYPE(Result *)
68−
69−#endif
plugins/Unity/scope.cppdeleted−413
@@ -1,413 +0,0 @@
1−/*
2− * Copyright (C) 2011 Canonical, Ltd.
3− *
4− * Authors:
5− * Florian Boucault <florian.boucault@canonical.com>
6− * Michal Hruby <michal.hruby@canonical.com>
7− *
8− * This program is free software; you can redistribute it and/or modify
9− * it under the terms of the GNU General Public License as published by
10− * the Free Software Foundation; version 3.
11− *
12− * This program is distributed in the hope that it will be useful,
13− * but WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15− * GNU General Public License for more details.
16− *
17− * You should have received a copy of the GNU General Public License
18− * along with this program. If not, see <http://www.gnu.org/licenses/>.
19− */
20−
21−// Self
22−#include "scope.h"
23−
24−// local
25−#include "categories.h"
26−#include "preview.h"
27−#include "variantutils.h"
28−
29−// Qt
30−#include <QUrl>
31−#include <QUrlQuery>
32−#include <QDebug>
33−#include <QtGui/QDesktopServices>
34−#include <QQmlEngine>
35−
36−#include <UnityCore/Variant.h>
37−#include <UnityCore/GLibWrapper.h>
38−
39−#include <libintl.h>
40−#include <glib.h>
41−
42−Scope::Scope(QObject *parent) : QObject(parent)
43− , m_formFactor("phone")
44− , m_isActive(false)
45− , m_searchInProgress(false)
46−{
47− m_categories.reset(new Categories(this));
48−
49− connect(this, &Scope::isActiveChanged, this, &Scope::scopeIsActiveChanged);
50−}
51−
52−QString Scope::id() const
53−{
54− return QString::fromStdString(m_unityScope->id());
55−}
56−
57−QString Scope::name() const
58−{
59− return QString::fromStdString(m_unityScope->name());
60−}
61−
62−QString Scope::iconHint() const
63−{
64− return QString::fromStdString(m_unityScope->icon_hint());
65−}
66−
67−QString Scope::description() const
68−{
69− return QString::fromStdString(m_unityScope->description());
70−}
71−
72−QString Scope::searchHint() const
73−{
74− return QString::fromStdString(m_unityScope->search_hint());
75−}
76−
77−bool Scope::searchInProgress() const
78−{
79− return m_searchInProgress;
80−}
81−
82−bool Scope::visible() const
83−{
84− return m_unityScope->visible();
85−}
86−
87−QString Scope::shortcut() const
88−{
89− return QString::fromStdString(m_unityScope->shortcut());
90−}
91−
92−bool Scope::connected() const
93−{
94− return m_unityScope->connected();
95−}
96−
97−Categories* Scope::categories() const
98−{
99− return m_categories.get();
100−}
101−
102−QString Scope::searchQuery() const
103−{
104− return m_searchQuery;
105−}
106−
107−QString Scope::noResultsHint() const
108−{
109− return m_noResultsHint;
110−}
111−
112−QString Scope::formFactor() const
113−{
114− return m_formFactor;
115−}
116−
117−bool Scope::isActive() const
118−{
119− return m_isActive;
120−}
121−
122−Filters* Scope::filters() const
123−{
124− return m_filters.get();
125−}
126−
127−void Scope::setSearchQuery(const QString& search_query)
128−{
129− /* Checking for m_searchQuery.isNull() which returns true only when the string
130− has never been set is necessary because when search_query is the empty
131− string ("") and m_searchQuery is the null string,
132− search_query != m_searchQuery is still true.
133− */
134− using namespace std::placeholders;
135−
136− if (m_searchQuery.isNull() || search_query != m_searchQuery) {
137− m_searchQuery = search_query;
138− m_cancellable.Renew();
139− m_unityScope->Search(search_query.toStdString(), std::bind(&Scope::onSearchFinished, this, _1, _2, _3), m_cancellable);
140− Q_EMIT searchQueryChanged();
141− if (!m_searchInProgress) {
142− m_searchInProgress = true;
143− Q_EMIT searchInProgressChanged();
144− }
145− }
146−}
147−
148−void Scope::setNoResultsHint(const QString& hint) {
149− if (hint != m_noResultsHint) {
150− m_noResultsHint = hint;
151− Q_EMIT noResultsHintChanged();
152− }
153−}
154−
155−void Scope::setFormFactor(const QString& form_factor) {
156− if (form_factor != m_formFactor) {
157− m_formFactor = form_factor;
158− if (m_unityScope) {
159− m_unityScope->form_factor = m_formFactor.toStdString();
160− synchronizeStates(); // will trigger a re-search
161− }
162− Q_EMIT formFactorChanged();
163− }
164−}
165−
166−void Scope::setActive(const bool active) {
167− if (active != m_isActive) {
168− m_isActive = active;
169− Q_EMIT isActiveChanged(m_isActive);
170− }
171−}
172−
173−unity::dash::LocalResult Scope::createLocalResult(const QVariant &uri, const QVariant &icon_hint,
174− const QVariant &category, const QVariant &result_type,
175− const QVariant &mimetype, const QVariant &title,
176− const QVariant &comment, const QVariant &dnd_uri,
177− const QVariant &metadata)
178−{
179− unity::dash::LocalResult res;
180− res.uri = uri.toString().toStdString();
181− res.icon_hint = icon_hint.toString().toStdString();
182− res.category_index = category.toUInt();
183− res.result_type = result_type.toUInt();
184− res.mimetype = mimetype.toString().toStdString();
185− res.name = title.toString().toStdString();
186− res.comment = comment.toString().toStdString();
187− res.dnd_uri = dnd_uri.toString().toStdString();
188− res.hints = convertToHintsMap(metadata);
189−
190− return res;
191−}
192−
193−// FIXME: Change to use row index.
194−void Scope::activate(const QVariant &uri, const QVariant &icon_hint, const QVariant &category,
195− const QVariant &result_type, const QVariant &mimetype, const QVariant &title,
196− const QVariant &comment, const QVariant &dnd_uri, const QVariant &metadata)
197−{
198− auto res = createLocalResult(uri, icon_hint, category, result_type, mimetype, title, comment, dnd_uri, metadata);
199− m_unityScope->Activate(res);
200−}
201−
202−// FIXME: Change to use row index.
203−void Scope::preview(const QVariant &uri, const QVariant &icon_hint, const QVariant &category,
204− const QVariant &result_type, const QVariant &mimetype, const QVariant &title,
205− const QVariant &comment, const QVariant &dnd_uri, const QVariant &metadata)
206−{
207− QVariant real_metadata(metadata);
208− // handle overridden results, since QML doesn't support defining maps
209− if (metadata.type() == QVariant::String) {
210− real_metadata = QVariant::fromValue(subscopeUriToMetadataHash(metadata.toString()));
211− }
212−
213− auto res = createLocalResult(uri, icon_hint, category, result_type, mimetype, title, comment, dnd_uri, real_metadata);
214− m_previewCancellable.Renew();
215−
216− // canned queries don't have previews, must be activated
217− if (uri.toString().startsWith("x-unity-no-preview-scopes-query://")) {
218− m_unityScope->Activate(res);
219− } else {
220− m_unityScope->Preview(res, nullptr, m_previewCancellable);
221− }
222−}
223−
224−void Scope::cancelActivation()
225−{
226− m_previewCancellable.Cancel();
227−}
228−
229−void Scope::onActivated(unity::dash::LocalResult const& result, unity::dash::ScopeHandledType type, unity::glib::HintsMap const& hints)
230−{
231− Q_EMIT activated();
232− // note: we will not get called on SHOW_PREVIEW, instead UnityCore will signal preview_ready.
233− switch (type)
234− {
235− case unity::dash::NOT_HANDLED:
236− fallbackActivate(QString::fromStdString(result.uri));
237− break;
238− case unity::dash::SHOW_DASH:
239− Q_EMIT showDash();
240− break;
241− case unity::dash::HIDE_DASH:
242− Q_EMIT hideDash();
243− break;
244− case unity::dash::GOTO_DASH_URI:
245− if (hints.find("goto-uri") != hints.end()) {
246− Q_EMIT gotoUri(QString::fromStdString(g_variant_get_string(hints.at("goto-uri"), nullptr)));
247− } else {
248− qWarning() << "Missing goto-uri hint for GOTO_DASH_URI activation reply";
249− }
250− break;
251− case unity::dash::PERFORM_SEARCH:
252− if (hints.find("query") != hints.end()) {
253− // note: this will emit searchQueryChanged, and shell will call setSearchQuery back with a new query,
254− // but it will get ignored.
255− setSearchQuery(QString::fromStdString(g_variant_get_string(hints.at("query"), nullptr)));
256− }
257− break;
258− default:
259− qWarning() << "Unhandled activation response:" << type;
260− }
261−}
262−
263−void Scope::onPreviewReady(unity::dash::LocalResult const& /* result */, unity::dash::Preview::Ptr const& preview)
264−{
265− Q_EMIT activated();
266− auto prv = Preview::newFromUnityPreview(preview);
267− // is this the best solution? QML may need to keep more than one preview instance around, so we can't own it.
268− // passing it by value is not possible.
269− QQmlEngine::setObjectOwnership(prv, QQmlEngine::JavaScriptOwnership);
270− Q_EMIT previewReady(prv);
271−}
272−
273−void Scope::fallbackActivate(const QString& uri)
274−{
275− /* Tries various methods to trigger a sensible action for the given 'uri'.
276− If it has no understanding of the given scheme it falls back on asking
277− Qt to open the uri.
278− */
279− QUrl url(uri);
280− if (url.scheme() == "file") {
281− /* Override the files place's default URI handler: we want the file
282− manager to handle opening folders, not the dash.
283−
284− Ref: https://bugs.launchpad.net/upicek/+bug/689667
285− */
286− QDesktopServices::openUrl(url);
287− return;
288− }
289− if (url.scheme() == "application") {
290− // get the full path to the desktop file
291− QString path(url.path().isEmpty() ? url.authority() : url.path());
292− if (path.startsWith("/")) {
293− Q_EMIT activateApplication(path);
294− } else {
295− // TODO: use the new desktop file finder/parser when it's ready
296− gchar* full_path = nullptr;
297− GKeyFile* key_file = g_key_file_new();
298− QString apps_path = "applications/" + path;
299− if (g_key_file_load_from_data_dirs(key_file, apps_path.toLocal8Bit().constData(), &full_path,
300− G_KEY_FILE_NONE, nullptr)) {
301− path = full_path;
302− Q_EMIT activateApplication(path);
303− } else {
304− qWarning() << "Unable to activate " << path;
305− }
306− g_key_file_free(key_file);
307− g_free(full_path);
308− }
309− return;
310− }
311−
312− qDebug() << "Trying to open" << uri;
313−
314− /* Try our luck */
315− QDesktopServices::openUrl(uri); //url?
316−}
317−
318−void Scope::setUnityScope(const unity::dash::Scope::Ptr& scope)
319−{
320− m_unityScope = scope;
321−
322− m_categories->setUnityScope(m_unityScope);
323− m_filters.reset(new Filters(m_unityScope->filters, this));
324−
325− m_unityScope->form_factor = m_formFactor.toStdString();
326− /* Property change signals */
327− m_unityScope->id.changed.connect(sigc::mem_fun(this, &Scope::idChanged));
328− m_unityScope->name.changed.connect(sigc::mem_fun(this, &Scope::nameChanged));
329− m_unityScope->icon_hint.changed.connect(sigc::mem_fun(this, &Scope::iconHintChanged));
330− m_unityScope->description.changed.connect(sigc::mem_fun(this, &Scope::descriptionChanged));
331− m_unityScope->search_hint.changed.connect(sigc::mem_fun(this, &Scope::searchHintChanged));
332− m_unityScope->visible.changed.connect(sigc::mem_fun(this, &Scope::visibleChanged));
333− m_unityScope->shortcut.changed.connect(sigc::mem_fun(this, &Scope::shortcutChanged));
334− m_unityScope->connected.changed.connect(sigc::mem_fun(this, &Scope::connectedChanged));
335− m_unityScope->results_dirty.changed.connect(sigc::mem_fun(this, &Scope::resultsDirtyToggled));
336−
337− /* FIXME: signal should be forwarded instead of calling the handler directly */
338− m_unityScope->activated.connect(sigc::mem_fun(this, &Scope::onActivated));
339−
340− m_unityScope->preview_ready.connect(sigc::mem_fun(this, &Scope::onPreviewReady));
341−
342− /* Synchronize local states with m_unityScope right now and whenever
343− m_unityScope becomes connected */
344− /* FIXME: should emit change notification signals for all properties */
345− connect(this, SIGNAL(connectedChanged(bool)), SLOT(synchronizeStates()));
346− synchronizeStates();
347−}
348−
349−unity::dash::Scope::Ptr Scope::unityScope() const
350−{
351− return m_unityScope;
352−}
353−
354−void Scope::synchronizeStates()
355−{
356− using namespace std::placeholders;
357−
358− if (connected()) {
359− /* Forward local states to m_unityScope */
360− if (!m_searchQuery.isNull()) {
361− m_cancellable.Renew();
362− m_unityScope->Search(m_searchQuery.toStdString(), std::bind(&Scope::onSearchFinished, this, _1, _2, _3), m_cancellable);
363− if (!m_searchInProgress) {
364− m_searchInProgress = true;
365− Q_EMIT searchInProgressChanged();
366− }
367− }
368− }
369−}
370−
371−void Scope::scopeIsActiveChanged()
372−{
373− if (!isActive() || !m_unityScope || !m_unityScope->results_dirty()) return;
374−
375− // force new search
376− synchronizeStates();
377−}
378−
379−void Scope::resultsDirtyToggled(bool results_dirty)
380−{
381− if (!results_dirty || !isActive()) return;
382−
383− // force new search
384− synchronizeStates();
385−}
386−
387−void Scope::onSearchFinished(std::string const& /* query */, unity::glib::HintsMap const& hints, unity::glib::Error const& err)
388−{
389− QString hint;
390−
391− GError* error = const_cast<unity::glib::Error&>(err);
392−
393− if (!err || !g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
394− if (m_searchInProgress) {
395− m_searchInProgress = false;
396− Q_EMIT searchInProgressChanged();
397− }
398− } else {
399− // no need to check the results hint, we're still searching
400− return;
401− }
402−
403− if (!m_unityScope->results()->count()) {
404− unity::glib::HintsMap::const_iterator it = hints.find("no-results-hint");
405− if (it != hints.end()) {
406− hint = QString::fromStdString(it->second.GetString());
407− } else {
408− hint = QString::fromUtf8(dgettext("unity", "Sorry, there is nothing that matches your search."));
409− }
410− }
411−
412− setNoResultsHint(hint);
413−}
plugins/Unity/scope.hdeleted−154
@@ -1,154 +0,0 @@
1−/*
2− * Copyright (C) 2011 Canonical, Ltd.
3− *
4− * Authors:
5− * Florian Boucault <florian.boucault@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#ifndef SCOPE_H
21−#define SCOPE_H
22−
23−// Qt
24−#include <QObject>
25−#include <QString>
26−#include <QMetaType>
27−
28−// libunity-core
29−#include <UnityCore/Scope.h>
30−#include <UnityCore/Results.h>
31−#include <UnityCore/GLibWrapper.h>
32−
33−#include "categories.h"
34−#include "filters.h"
35−
36−class Preview;
37−
38−class Scope : public QObject
39−{
40− Q_OBJECT
41−
42− Q_PROPERTY(QString id READ id NOTIFY idChanged)
43− Q_PROPERTY(QString name READ name NOTIFY nameChanged)
44− Q_PROPERTY(QString iconHint READ iconHint NOTIFY iconHintChanged)
45− Q_PROPERTY(QString description READ description NOTIFY descriptionChanged)
46− Q_PROPERTY(QString searchHint READ searchHint NOTIFY searchHintChanged)
47− Q_PROPERTY(bool searchInProgress READ searchInProgress NOTIFY searchInProgressChanged)
48− Q_PROPERTY(bool visible READ visible NOTIFY visibleChanged)
49− Q_PROPERTY(QString shortcut READ shortcut NOTIFY shortcutChanged)
50− Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged)
51− Q_PROPERTY(Categories* categories READ categories NOTIFY categoriesChanged)
52− Q_PROPERTY(Filters* filters READ filters NOTIFY filtersChanged)
53−
54− Q_PROPERTY(QString searchQuery READ searchQuery WRITE setSearchQuery NOTIFY searchQueryChanged)
55− Q_PROPERTY(QString noResultsHint READ noResultsHint WRITE setNoResultsHint NOTIFY noResultsHintChanged)
56− Q_PROPERTY(QString formFactor READ formFactor WRITE setFormFactor NOTIFY formFactorChanged)
57− Q_PROPERTY(bool isActive READ isActive WRITE setActive NOTIFY isActiveChanged)
58−
59−public:
60− explicit Scope(QObject *parent = 0);
61−
62− /* getters */
63− QString id() const;
64− QString name() const;
65− QString iconHint() const;
66− QString description() const;
67− QString searchHint() const;
68− bool visible() const;
69− QString shortcut() const;
70− bool connected() const;
71− bool searchInProgress() const;
72− Categories* categories() const;
73− Filters* filters() const;
74− QString searchQuery() const;
75− QString noResultsHint() const;
76− QString formFactor() const;
77− bool isActive() const;
78−
79− /* setters */
80− void setSearchQuery(const QString& search_query);
81− void setNoResultsHint(const QString& hint);
82− void setFormFactor(const QString& form_factor);
83− void setActive(const bool);
84−
85− Q_INVOKABLE void activate(const QVariant &uri, const QVariant &icon_hint, const QVariant &category,
86− const QVariant &result_type, const QVariant &mimetype, const QVariant &title,
87− const QVariant &comment, const QVariant &dnd_uri, const QVariant &metadata);
88− Q_INVOKABLE void preview(const QVariant &uri, const QVariant &icon_hint, const QVariant &category,
89− const QVariant &result_type, const QVariant &mimetype, const QVariant &title,
90− const QVariant &comment, const QVariant &dnd_uri, const QVariant &metadata);
91− Q_INVOKABLE void cancelActivation();
92−
93− void setUnityScope(const unity::dash::Scope::Ptr& scope);
94− unity::dash::Scope::Ptr unityScope() const;
95−
96−Q_SIGNALS:
97− void idChanged(const std::string&);
98− void dbusNameChanged(const std::string&);
99− void dbusPathChanged(const std::string&);
100− void nameChanged(const std::string&);
101− void iconHintChanged(const std::string&);
102− void descriptionChanged(const std::string&);
103− void searchHintChanged(const std::string&);
104− void searchInProgressChanged();
105− void visibleChanged(bool);
106− void shortcutChanged(const std::string&);
107− void connectedChanged(bool);
108− void categoriesChanged();
109− void searchQueryChanged();
110− void noResultsHintChanged();
111− void formFactorChanged();
112− void isActiveChanged(bool);
113− void filtersChanged();
114−
115− // signals triggered by activate(..) or preview(..) requests.
116− void previewReady(Preview *preview);
117− void showDash();
118− void hideDash();
119− void gotoUri(const QString &uri);
120− void activated();
121−
122− void activateApplication(const QString &desktop);
123−
124−private Q_SLOTS:
125− void synchronizeStates();
126− void scopeIsActiveChanged();
127− void onSearchFinished(std::string const &, unity::glib::HintsMap const &, unity::glib::Error const&);
128−
129−private:
130− unity::dash::LocalResult createLocalResult(const QVariant &uri, const QVariant &icon_hint,
131− const QVariant &category, const QVariant &result_type,
132− const QVariant &mimetype, const QVariant &title,
133− const QVariant &comment, const QVariant &dnd_uri,
134− const QVariant &metadata);
135− void onActivated(unity::dash::LocalResult const& result, unity::dash::ScopeHandledType type, unity::glib::HintsMap const& hints);
136− void onPreviewReady(unity::dash::LocalResult const& result, unity::dash::Preview::Ptr const& preview);
137− void fallbackActivate(const QString& uri);
138− void resultsDirtyToggled(bool);
139−
140− unity::dash::Scope::Ptr m_unityScope;
141− std::unique_ptr<Categories> m_categories;
142− std::unique_ptr<Filters> m_filters;
143− QString m_searchQuery;
144− QString m_noResultsHint;
145− QString m_formFactor;
146− bool m_isActive;
147− bool m_searchInProgress;
148− unity::glib::Cancellable m_cancellable;
149− unity::glib::Cancellable m_previewCancellable;
150−};
151−
152−Q_DECLARE_METATYPE(Scope*)
153−
154−#endif // SCOPE_H
plugins/Unity/scopes.cppdeleted−176
@@ -1,176 +0,0 @@
1−/*
2− * Copyright (C) 2011 Canonical, Ltd.
3− *
4− * Authors:
5− * Florian Boucault <florian.boucault@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−// Self
21−#include "scopes.h"
22−
23−// Local
24−#include "scope.h"
25−
26−// Qt
27−#include <QDebug>
28−#include <QtCore/QStringList>
29−#include <QtGui/QKeySequence>
30−
31−Scopes::Scopes(QObject *parent)
32− : QAbstractListModel(parent)
33− , m_unityScopes(std::make_shared<unity::dash::GSettingsScopes>())
34− , m_loaded(false)
35−{
36− m_roles[Scopes::RoleScope] = "scope";
37− m_roles[Scopes::RoleId] = "id";
38− m_roles[Scopes::RoleVisible] = "visible";
39−
40− m_unityScopes->scope_added.connect(sigc::mem_fun(this, &Scopes::onScopeAdded));
41− m_unityScopes->scope_removed.connect(sigc::mem_fun(this, &Scopes::onScopeRemoved));
42− m_unityScopes->scopes_reordered.connect(sigc::mem_fun(this, &Scopes::onScopesReordered));
43− m_unityScopes->LoadScopes();
44−}
45−
46−QHash<int, QByteArray> Scopes::roleNames() const
47−{
48− return m_roles;
49−}
50−
51−int Scopes::rowCount(const QModelIndex& parent) const
52−{
53− Q_UNUSED(parent)
54−
55− return m_scopes.count();
56−}
57−
58−QVariant Scopes::data(const QModelIndex& index, int role) const
59−{
60− Q_UNUSED(role)
61−
62− if (!index.isValid()) {
63− return QVariant();
64− }
65−
66− Scope* scope = m_scopes.at(index.row());
67−
68− if (role == Scopes::RoleScope) {
69− return QVariant::fromValue(scope);
70− } else if (role == Scopes::RoleId) {
71− return QVariant::fromValue(scope->id());
72− } else if (role == Scopes::RoleVisible) {
73− return QVariant::fromValue(scope->visible());
74− } else {
75− return QVariant();
76− }
77−}
78−
79−QVariant Scopes::get(int row) const
80−{
81− return data(QAbstractListModel::index(row), 0);
82−}
83−
84−QVariant Scopes::get(const QString& scope_id) const
85−{
86− Q_FOREACH(Scope* scope, m_scopes) {
87− if (scope->id() == scope_id) {
88− return QVariant::fromValue(scope);
89− }
90− }
91−
92− return QVariant();
93−}
94−
95−bool Scopes::loaded() const
96−{
97− return m_loaded;
98−}
99−
100−void Scopes::onScopeAdded(const unity::dash::Scope::Ptr& scope, int /*position*/)
101−{
102− int index = m_scopes.count();
103− beginInsertRows(QModelIndex(), index, index);
104− addUnityScope(scope);
105− endInsertRows();
106−
107− // FIXME: do only once after all loaded?
108− m_loaded = true;
109− Q_EMIT loadedChanged(m_loaded);
110−}
111−
112−void Scopes::onScopesLoaded()
113−{
114−}
115−
116−void Scopes::onScopeRemoved(const unity::dash::Scope::Ptr& scope)
117−{
118− auto id = QString::fromStdString(scope->id);
119− auto index = findScopeById(id);
120− if (index >= 0) {
121− beginRemoveRows(QModelIndex(), index, index);
122− removeUnityScope(index);
123− endRemoveRows();
124−
125− Q_EMIT scopeRemoved(id, index);
126− }
127−}
128−
129−void Scopes::onScopesReordered(const unity::dash::Scopes::ScopeList& scopes)
130−{
131− // FIXME Should use beginMoveRows()/endMoveRows() to not recreate the UI for every scope.
132− beginResetModel();
133−
134− // remove existing scopes
135− for (auto i=m_scopes.count()-1; i>=0; i--) {
136− removeUnityScope(i);
137− }
138−
139− // re-create scopes
140− for (uint i=0; i<scopes.size(); i++) {
141− addUnityScope(scopes[i]);
142− }
143− endResetModel();
144−}
145−
146−void Scopes::onScopePropertyChanged()
147−{
148− QModelIndex scopeIndex = index(m_scopes.indexOf(qobject_cast<Scope*>(sender())));
149− Q_EMIT dataChanged(scopeIndex, scopeIndex);
150−}
151−
152−void Scopes::addUnityScope(const unity::dash::Scope::Ptr& unity_scope)
153−{
154− Scope* scope = new Scope(this);
155− scope->setUnityScope(unity_scope);
156− /* DOCME */
157− QObject::connect(scope, SIGNAL(visibleChanged(bool)), this, SLOT(onScopePropertyChanged()));
158− m_scopes.append(scope);
159−}
160−
161−void Scopes::removeUnityScope(int index)
162−{
163− Scope* scope = m_scopes.takeAt(index);
164−
165− delete scope;
166−}
167−
168−int Scopes::findScopeById(const QString& scope_id)
169−{
170− for (int i=0; i<m_scopes.count(); i++) {
171− if (m_scopes[i]->id() == scope_id) {
172− return i;
173− }
174− }
175− return -1;
176−}
plugins/Unity/scopes.hdeleted−94
@@ -1,94 +0,0 @@
1−/*
2− * Copyright (C) 2011 Canonical, Ltd.
3− *
4− * Authors:
5− * Florian Boucault <florian.boucault@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#ifndef SCOPES_H
21−#define SCOPES_H
22−
23−// Qt
24−#include <QAbstractListModel>
25−#include <QList>
26−
27−// libunity-core
28−#include <UnityCore/Scope.h>
29−#include <UnityCore/GSettingsScopes.h>
30−
31−namespace unity
32−{
33−namespace dash
34−{
35−class Scopes;
36−}
37−}
38−
39−class Hotkey;
40−class Scope;
41−
42−class Scopes : public QAbstractListModel
43−{
44− Q_OBJECT
45−
46− Q_ENUMS(Roles)
47−
48− Q_PROPERTY(bool loaded READ loaded NOTIFY loadedChanged)
49−
50−public:
51− explicit Scopes(QObject *parent = 0);
52− ~Scopes() = default;
53−
54− enum Roles {
55− RoleScope,
56− RoleId,
57− RoleVisible
58− };
59−
60− QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
61− Q_INVOKABLE int rowCount(const QModelIndex& parent = QModelIndex()) const;
62−
63− Q_INVOKABLE QVariant get(int row) const;
64− Q_INVOKABLE QVariant get(const QString& scope_id) const;
65−
66− QHash<int, QByteArray> roleNames() const;
67−
68− bool loaded() const;
69−
70−Q_SIGNALS:
71− void activateScopeRequested(const QString& scope_id);
72− void loadedChanged(bool loaded);
73− void scopeRemoved(const QString& scope_id, int index);
74−
75−private Q_SLOTS:
76− void onScopesLoaded();
77− void onScopeAdded(const unity::dash::Scope::Ptr& scope, int position);
78− void onScopeRemoved(const unity::dash::Scope::Ptr& scope);
79− void onScopesReordered(const unity::dash::Scopes::ScopeList& scopes);
80− void onScopePropertyChanged();
81−
82−private:
83− unity::dash::GSettingsScopesReader::Ptr m_scopesReader;
84− unity::dash::Scopes::Ptr m_unityScopes;
85− QList<Scope*> m_scopes;
86− QHash<int, QByteArray> m_roles;
87− bool m_loaded;
88−
89− void addUnityScope(const unity::dash::Scope::Ptr& unity_scope);
90− void removeUnityScope(int index);
91− int findScopeById(const QString& scope_id);
92−};
93−
94−#endif // SCOPES_H
plugins/Unity/showallfilteroption.cppdeleted−60
@@ -1,60 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−// self
21−#include "showallfilteroption.h"
22−
23−#include <libintl.h>
24−
25−unsigned int ShowAllFilterOption::m_showAllCount = 0;
26−
27−ShowAllFilterOption::ShowAllFilterOption(QObject *parent) :
28− AbstractFilterOption(parent),
29− m_active(false)
30−{
31− m_id = QString("show_all::%1").arg(m_showAllCount++);
32−}
33−
34−QString ShowAllFilterOption::id() const
35−{
36− return m_id;
37−}
38−
39−QString ShowAllFilterOption::name() const
40−{
41− return QString::fromUtf8(dgettext("unity", "All"));
42−}
43−
44−QString ShowAllFilterOption::iconHint() const
45−{
46− return QString::Null();
47−}
48−
49−bool ShowAllFilterOption::active() const
50−{
51− return m_active;
52−}
53−
54−void ShowAllFilterOption::setActive(bool active)
55−{
56− if (active != m_active) {
57− m_active = active;
58− Q_EMIT activeChanged(m_active);
59− }
60−}
plugins/Unity/showallfilteroption.hdeleted−51
@@ -1,51 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#ifndef SHOWALLFILTEROPTION_H
21−#define SHOWALLFILTEROPTION_H
22−
23−// local
24−#include "abstractfilteroption.h"
25−
26−class Q_DECL_EXPORT ShowAllFilterOption : public AbstractFilterOption
27−{
28− Q_OBJECT
29−
30−public:
31− explicit ShowAllFilterOption(QObject *parent = nullptr);
32−
33− /* getters */
34− QString id() const override;
35− QString name() const override;
36− QString iconHint() const override;
37− bool active() const override;
38−
39− /* setters */
40− void setActive(bool active) override;
41−
42−private:
43− bool m_active;
44− QString m_id;
45−
46− static unsigned int m_showAllCount;
47−};
48−
49−Q_DECLARE_METATYPE(ShowAllFilterOption*)
50−
51−#endif // SHOWALLFILTEROPTION_H
plugins/Unity/signalslist.cppdeleted−39
@@ -1,39 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#include "signalslist.h"
21−
22−void SignalsList::append(const sigc::connection &c)
23−{
24− m_signals.append(c);
25−}
26−
27−void SignalsList::disconnectAll()
28−{
29− Q_FOREACH(auto sig, m_signals) {
30− sig.disconnect();
31− }
32− m_signals.clear();
33−}
34−
35−SignalsList& SignalsList::operator<<(const sigc::connection &c)
36−{
37− append(c);
38− return *this;
39−}
plugins/Unity/signalslist.hdeleted−38
@@ -1,38 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#ifndef SIGNALSLIST_H
21−#define SIGNALSLIST_H
22−
23−#include <QList>
24−#include <sigc++/sigc++.h>
25−
26−class Q_DECL_EXPORT SignalsList
27−{
28−public:
29− void append(const sigc::connection &c);
30− void disconnectAll();
31−
32− SignalsList& operator<<(const sigc::connection &c);
33−
34−private:
35− QList<sigc::connection> m_signals;
36−};
37−
38−#endif // SIGNALSLIST_H
plugins/Unity/socialpreview.cppdeleted−87
@@ -1,87 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#include "socialpreview.h"
21−#include "socialpreviewcomment.h"
22−#include "iconutils.h"
23−
24−#include <QDebug>
25−
26−SocialPreview::SocialPreview(QObject *parent):
27− Preview(parent),
28− m_unitySocialPreview(nullptr)
29−{
30−}
31−
32−QString SocialPreview::sender() const
33−{
34− if (m_unitySocialPreview) {
35− return QString::fromStdString(m_unitySocialPreview->sender());
36− } else {
37− qWarning() << "Preview not set";
38− }
39− return QString();
40−}
41−
42−QString SocialPreview::content() const
43−{
44− if (m_unitySocialPreview) {
45− return QString::fromStdString(m_unitySocialPreview->content());
46− } else {
47− qWarning() << "Preview not set";
48− }
49− return QString();
50−}
51−
52−QString SocialPreview::avatar() const
53−{
54− if (m_unitySocialPreview) {
55− auto giconString = g_icon_to_string(m_unitySocialPreview->avatar());
56− QString result(gIconToDeclarativeImageProviderString(QString::fromUtf8(giconString)));
57− g_free(giconString);
58− return result;
59− } else {
60− qWarning() << "Preview not set";
61− }
62− return QString();
63−}
64−
65−QVariant SocialPreview::comments()
66−{
67− return QVariant::fromValue(m_comments);
68−}
69−
70−void SocialPreview::setUnityPreview(unity::dash::Preview::Ptr unityPreview)
71−{
72− m_unitySocialPreview = std::dynamic_pointer_cast<unity::dash::SocialPreview>(unityPreview);
73− qDeleteAll(m_comments);
74− m_comments.clear();
75−
76− if (m_unitySocialPreview) {
77− for (auto unityComment: m_unitySocialPreview->GetComments()) {
78− auto comment = new SocialPreviewComment(this);
79− comment->setUnityComment(unityComment);
80− m_comments.append(comment);
81−
82− Q_EMIT previewChanged();
83− }
84− } else {
85− qWarning() << "Incorrect preview type";
86− }
87−}
plugins/Unity/socialpreview.hdeleted−63
@@ -1,63 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#ifndef SOCIALPREVIEW_H
21−#define SOCIALPREVIEW_H
22−
23−// local
24−#include "preview.h"
25−
26−// Qt
27−#include <QObject>
28−#include <QList>
29−#include <QMetaType>
30−
31−// libunity-core
32−#include <UnityCore/SocialPreview.h>
33−
34−class Q_DECL_EXPORT SocialPreview: public Preview
35−{
36− Q_OBJECT
37−
38− Q_PROPERTY(QString sender READ sender NOTIFY previewChanged)
39− Q_PROPERTY(QString content READ content NOTIFY previewChanged)
40− Q_PROPERTY(QString avatar READ avatar NOTIFY previewChanged)
41−
42−public:
43− explicit SocialPreview(QObject *parent = 0);
44−
45− QString sender() const;
46− QString content() const;
47− QString avatar() const;
48− QVariant comments();
49−
50−Q_SIGNALS:
51− void previewChanged();
52−
53−protected:
54− void setUnityPreview(unity::dash::Preview::Ptr unityPreview) override;
55−
56−private:
57− unity::dash::SocialPreview::Ptr m_unitySocialPreview;
58− QList<QObject *> m_comments;
59−};
60−
61−Q_DECLARE_METATYPE(SocialPreview *)
62−
63−#endif
plugins/Unity/socialpreviewcomment.cppdeleted−63
@@ -1,63 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−// local
21−#include "socialpreviewcomment.h"
22−
23−SocialPreviewComment::SocialPreviewComment(QObject *parent) :
24− QObject(parent)
25−{
26−}
27−
28−void SocialPreviewComment::setUnityComment(unity::dash::SocialPreview::CommentPtr unityComment)
29−{
30− m_unityComment = unityComment;
31−}
32−
33−QString SocialPreviewComment::id() const
34−{
35− if (m_unityComment) {
36− return QString::fromStdString(m_unityComment->id);
37− }
38− return QString();
39−}
40−
41−QString SocialPreviewComment::displayName() const
42−{
43− if (m_unityComment) {
44− return QString::fromStdString(m_unityComment->display_name);
45− }
46− return QString();
47−}
48−
49−QString SocialPreviewComment::content() const
50−{
51− if (m_unityComment) {
52− return QString::fromStdString(m_unityComment->content);
53− }
54− return QString();
55−}
56−
57−QString SocialPreviewComment::time() const
58−{
59− if (m_unityComment) {
60− return QString::fromStdString(m_unityComment->time);
61− }
62− return QString();
63−}
plugins/Unity/socialpreviewcomment.hdeleted−57
@@ -1,57 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#ifndef SOCIALPREVIEWCOMMENT_H
21−#define SOCIALPREVIEWCOMMENT_H
22−
23−// Qt
24−#include <QObject>
25−#include <QMetaType>
26−
27−// libunity-core
28−#include <UnityCore/SocialPreview.h>
29−
30−class Q_DECL_EXPORT SocialPreviewComment : public QObject
31−{
32− Q_OBJECT
33−
34− Q_PROPERTY(QString id READ id NOTIFY socialPreviewCommentChanged)
35− Q_PROPERTY(QString displayName READ displayName NOTIFY socialPreviewCommentChanged)
36− Q_PROPERTY(QString content READ content NOTIFY socialPreviewCommentChanged)
37− Q_PROPERTY(QString time READ time NOTIFY socialPreviewCommentChanged)
38−
39−public:
40− explicit SocialPreviewComment(QObject *parent = 0);
41− void setUnityComment(unity::dash::SocialPreview::CommentPtr unityComment);
42−
43− QString id() const;
44− QString displayName() const;
45− QString content() const;
46− QString time() const;
47−
48−Q_SIGNALS:
49− void socialPreviewCommentChanged();
50−
51−private:
52− unity::dash::SocialPreview::CommentPtr m_unityComment;
53−};
54−
55−Q_DECLARE_METATYPE(SocialPreviewComment *)
56−
57−#endif
plugins/Unity/unityoptionsmodel.cppdeleted−68
@@ -1,68 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−// self
21−#include "unityoptionsmodel.h"
22−
23−// local
24−#include "filteroption.h"
25−
26−UnityOptionsModel::UnityOptionsModel(QObject *parent,
27− const std::vector<unity::dash::FilterOption::Ptr> options,
28− sigc::signal<void, unity::dash::FilterOption::Ptr> optionAdded,
29− sigc::signal<void, unity::dash::FilterOption::Ptr> optionRemoved,
30− bool showAllOption) :
31− GenericOptionsModel(showAllOption, parent)
32−{
33− setOptions(options, optionAdded, optionRemoved);
34−}
35−
36−void UnityOptionsModel::setOptions(const std::vector<unity::dash::FilterOption::Ptr> options,
37− sigc::signal<void, unity::dash::FilterOption::Ptr> optionAdded,
38− sigc::signal<void, unity::dash::FilterOption::Ptr> optionRemoved)
39−{
40− for (unsigned int i=0; i<options.size(); i++)
41− {
42− addOption(new FilterOption(options[i], this));
43− }
44− optionAdded.connect(sigc::mem_fun(this, &UnityOptionsModel::onOptionAdded));
45− optionRemoved.connect(sigc::mem_fun(this, &UnityOptionsModel::onOptionRemoved));
46−}
47−
48−void UnityOptionsModel::onOptionAdded(unity::dash::FilterOption::Ptr option)
49−{
50− int index = m_options.count();
51− if (index >= 0)
52− {
53− beginInsertRows(QModelIndex(), index, index);
54− addOption(new FilterOption(option, this));
55− endInsertRows();
56− }
57−}
58−
59−void UnityOptionsModel::onOptionRemoved(unity::dash::FilterOption::Ptr option)
60−{
61− auto index = indexOf(QString::fromStdString(option->id));
62− if (index >= 0)
63− {
64− beginRemoveRows(QModelIndex(), index, index);
65− removeOption(index);
66− endRemoveRows();
67− }
68−}
plugins/Unity/unityoptionsmodel.hdeleted−50
@@ -1,50 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#ifndef UNITYOPTIONSMODEL_H
21−#define UNITYOPTIONSMODEL_H
22−
23−#include "genericoptionsmodel.h"
24−
25−// libunity-core
26−#include <UnityCore/Filter.h>
27−
28−#include <sigc++/signal.h>
29−
30−class UnityOptionsModel : public GenericOptionsModel
31−{
32− Q_OBJECT
33−
34−public:
35− UnityOptionsModel(QObject *parent,
36− const std::vector<unity::dash::FilterOption::Ptr> options,
37− sigc::signal<void, unity::dash::FilterOption::Ptr> optionAdded,
38− sigc::signal<void, unity::dash::FilterOption::Ptr> optionRemoved,
39− bool showAllOption);
40−
41−private:
42− void setOptions(const std::vector<unity::dash::FilterOption::Ptr> options,
43− sigc::signal<void, unity::dash::FilterOption::Ptr> optionAdded,
44− sigc::signal<void, unity::dash::FilterOption::Ptr> optionRemoved);
45−
46− void onOptionAdded(unity::dash::FilterOption::Ptr option);
47− void onOptionRemoved(unity::dash::FilterOption::Ptr option);
48−};
49−
50−#endif // UNITYOPTIONSMODEL_H
plugins/Unity/variantutils.cppdeleted−82
@@ -1,82 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#include <QUrl>
21−#include <QUrlQuery>
22−#include <QStringList>
23−
24−#include <deelistmodel.h>
25−#include "variantutils.h"
26−
27−unity::glib::HintsMap convertToHintsMap(const QHash<QString, QVariant> &val)
28−{
29− unity::glib::HintsMap hintsMap;
30− QHash<QString, QVariant>::const_iterator it = val.constBegin();
31− while (it != val.constEnd()) {
32− hintsMap[it.key().toStdString()] = DeeListModel::DataFromVariant(it.value());
33− ++it;
34− }
35− return hintsMap;
36−}
37−
38−unity::glib::HintsMap convertToHintsMap(const QVariant &var)
39−{
40− if (var.type() == QVariant::Hash) {
41− unity::glib::HintsMap hintsMap;
42− const auto hash = var.toHash();
43− return convertToHintsMap(hash);
44− }
45− return unity::glib::HintsMap();
46−}
47−
48−QVariantHash convertToQVariantHash(const unity::glib::HintsMap& var)
49−{
50− QVariantHash hash;
51− for (auto hint: var) {
52− hash.insert(QString::fromStdString(hint.first), DeeListModel::VariantForData(hint.second));
53− }
54− return hash;
55−}
56−
57−/* This will translate uris in the form of:
58− * "subscope:master.scope/sub.scope?foo=bar"
59− * into a QVariantHash that can be passed as a metadata field to scope.
60− */
61−QVariantHash subscopeUriToMetadataHash(const QString &metadata_string)
62−{
63− QUrl metadata_url(metadata_string);
64− if (metadata_url.scheme() == QLatin1String("subscope")) {
65− QString subscope_uri(metadata_url.toString(QUrl::RemoveScheme | QUrl::RemoveQuery));
66− QVariantHash new_metadata;
67− QUrlQuery query(metadata_url.query());
68− QList<QPair<QString,QString>> queryItems(query.queryItems());
69− for (auto it = queryItems.begin(); it != queryItems.end(); ++it) {
70− new_metadata[it->first] = QVariant::fromValue(it->second);
71− }
72− QStringList parts(subscope_uri.split(QChar('/')));
73− for (int i = parts.size() - 1; i >= 0; i--) {
74− QVariantHash inner;
75− inner["scope-id"] = QVariant::fromValue(parts[i]);
76− inner["content"] = QVariant::fromValue(new_metadata);
77− new_metadata = inner;
78− }
79− return new_metadata;
80− }
81− return QVariantHash();
82−}
plugins/Unity/variantutils.hdeleted−35
@@ -1,35 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#ifndef VARIANTUTILS_H
21−#define VARIANTUTILS_H
22−
23−#include <glib.h>
24−#include <QVariant>
25−
26−// libunity-core
27−#include <UnityCore/Variant.h>
28−
29−unity::glib::HintsMap convertToHintsMap(const QHash<QString, QVariant> &val);
30−unity::glib::HintsMap convertToHintsMap(const QVariant &var);
31−QVariantHash convertToQVariantHash(const unity::glib::HintsMap &var);
32−/* used in tests, so we have to export it */
33−Q_DECL_EXPORT QVariantHash subscopeUriToMetadataHash(const QString &metadata_string);
34−
35−#endif
plugins/Utils/CMakeLists.txt+1−2
@@ -12,11 +12,10 @@ include_directories(
12
12
13set(QMLPLUGIN_SRC
13set(QMLPLUGIN_SRC
14 albumartprovider.cpp
14 albumartprovider.cpp
15− applicationpaths.h
15+ bottombarvisibilitycommunicatorshell.cpp
16 mediaartcache.cpp
16 mediaartcache.cpp
17 qlimitproxymodelqml.cpp
17 qlimitproxymodelqml.cpp
18 qsortfilterproxymodelqml.cpp
18 qsortfilterproxymodelqml.cpp
19− ubuntuwindow.cpp
20 unitymenumodelpaths.cpp
19 unitymenumodelpaths.cpp
21 plugin.cpp
20 plugin.cpp
22 )
21 )
plugins/Utils/albumartprovider.cpp+10−7
@@ -32,6 +32,7 @@
32#include <QByteArray>
32#include <QByteArray>
33#include <QImage>
33#include <QImage>
34#include <QUrl>
34#include <QUrl>
35+#include <QUrlQuery>
35
36
36using namespace std;
37using namespace std;
37
38
@@ -65,6 +66,9 @@ AlbumArtProvider::~AlbumArtProvider()
65std::string AlbumArtProvider::get_lastfm_url(const albuminfo &ai) {
66std::string AlbumArtProvider::get_lastfm_url(const albuminfo &ai) {
66 QString artist = QString::fromStdString(ai.artist);
67 QString artist = QString::fromStdString(ai.artist);
67 QString album = QString::fromStdString(ai.album);
68 QString album = QString::fromStdString(ai.album);
69+ // audioscrobbler wants it without any / (as it would break the URL)
70+ artist.remove('/');
71+ album.remove('/');
68
72
69 /// @todo: this is the old API which will probably get axed at some point in the future
73 /// @todo: this is the old API which will probably get axed at some point in the future
70 /// The new 2.0 API requires an API key, but supports JSON output, etc, so switching
74 /// 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
200QImage AlbumArtProvider::requestImage(const QString &id, QSize *realSize, const QSize &requestedSize) {
204QImage AlbumArtProvider::requestImage(const QString &id, QSize *realSize, const QSize &requestedSize) {
201 Q_UNUSED(requestedSize)
205 Q_UNUSED(requestedSize)
202
206
203− const QStringList parts = id.split("/");
207+ QUrlQuery query(id);
204− if (parts.size() != 2) {
208+ if (!query.hasQueryItem(QStringLiteral("artist")) || !query.hasQueryItem(QStringLiteral("album"))) {
205 qWarning() << "Invalid albumart uri:" << id;
209 qWarning() << "Invalid albumart uri:" << id;
206 return QImage(QString::fromStdString(DEFAULT_ALBUM_ART));
210 return QImage(QString::fromStdString(DEFAULT_ALBUM_ART));
207 }
211 }
208− const std::string artist = QUrl::fromPercentEncoding(parts[0].toUtf8()).toStdString();
212+ const QString artist = query.queryItemValue(QStringLiteral("artist"), QUrl::FullyEncoded);
209− const std::string album = QUrl::fromPercentEncoding(parts[1].toUtf8()).toStdString();
213+ const QString album = query.queryItemValue(QStringLiteral("album"), QUrl::FullyEncoded);
210
214
211 std::string tgt_path;
215 std::string tgt_path;
212 try {
216 try {
213− tgt_path = get_image(artist, album);
217+ tgt_path = get_image(artist.toStdString(), album.toStdString());
214 if(!tgt_path.empty()) {
218 if(!tgt_path.empty()) {
215− QString tgt(tgt_path.c_str());
216 QImage image;
219 QImage image;
217− image.load(tgt);
220+ image.load(QString::fromStdString(tgt_path));
218 // FIXME: Rescale to requested size preserving aspect.
221 // FIXME: Rescale to requested size preserving aspect.
219 *realSize = image.size();
222 *realSize = image.size();
220 return image;
223 return image;
plugins/Utils/applicationpaths.hdeleted−38
@@ -1,38 +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− * Authored by: Nick Dedekind <nick.dedekind@canonical.com>
17− */
18−
19−
20−#ifndef APPLICATION_PATHS_H
21−#define APPLICATION_PATHS_H
22−
23−#include <QObject>
24−#include "paths.h"
25−
26−class ApplicationPaths : public QObject
27−{
28− Q_OBJECT
29−public:
30− Q_INVOKABLE bool isRunningInstalled() const { return ::isRunningInstalled(); }
31− Q_INVOKABLE QString shellAppDirectory() const { return ::shellAppDirectory(); }
32− Q_INVOKABLE QStringList overrideImportPaths() const { return ::overrideImportPaths(); }
33− Q_INVOKABLE QStringList fallbackImportPaths() const { return ::fallbackImportPaths(); }
34− Q_INVOKABLE QStringList shellDataDirs() const { return ::shellDataDirs(); }
35− Q_INVOKABLE QString sourceDirectory() const { return ::sourceDirectory(); }
36−};
37−
38−#endif // APPLICATION_PATHS_H
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+11−9
@@ -18,6 +18,8 @@
18
18
19// Qt
19// Qt
20#include <QtQml/qqml.h>
20#include <QtQml/qqml.h>
21+#include <QDBusConnection>
22+#include <QQmlContext>
21#include <QtQuick/QQuickWindow>
23#include <QtQuick/QQuickWindow>
22#include <QDebug>
24#include <QDebug>
23// self
25// self
@@ -25,17 +27,13 @@
25
27
26// local
28// local
27#include "albumartprovider.h"
29#include "albumartprovider.h"
28−#include "applicationpaths.h"
30+#include "bottombarvisibilitycommunicatorshell.h"
29#include "qlimitproxymodelqml.h"
31#include "qlimitproxymodelqml.h"
30#include "qsortfilterproxymodelqml.h"
32#include "qsortfilterproxymodelqml.h"
31−#include "ubuntuwindow.h"
32#include "unitymenumodelpaths.h"
33#include "unitymenumodelpaths.h"
33
34
34−static QObject* applicationsPathsSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
35+static const char* BOTTOM_BAR_VISIBILITY_COMMUNICATOR_DBUS_PATH = "/BottomBarVisibilityCommunicator";
35− Q_UNUSED(engine);
36+static const char* DBUS_SERVICE = "com.canonical.Shell.BottomBarVisibilityCommunicator";
36− Q_UNUSED(scriptEngine);
37− return new ApplicationPaths;
38−}
39
37
40void UtilsPlugin::registerTypes(const char *uri)
38void UtilsPlugin::registerTypes(const char *uri)
41{
39{
@@ -44,8 +42,7 @@ void UtilsPlugin::registerTypes(const char *uri)
44 qmlRegisterType<QLimitProxyModelQML>(uri, 0, 1, "LimitProxyModel");
42 qmlRegisterType<QLimitProxyModelQML>(uri, 0, 1, "LimitProxyModel");
45 qmlRegisterType<QSortFilterProxyModelQML>(uri, 0, 1, "SortFilterProxyModel");
43 qmlRegisterType<QSortFilterProxyModelQML>(uri, 0, 1, "SortFilterProxyModel");
46 qmlRegisterType<UnityMenuModelPaths>(uri, 0, 1, "UnityMenuModelPaths");
44 qmlRegisterType<UnityMenuModelPaths>(uri, 0, 1, "UnityMenuModelPaths");
47− qmlRegisterExtendedType<QQuickWindow, UbuntuWindow>(uri, 0, 1, "Window");
45+ qmlRegisterUncreatableType<BottomBarVisibilityCommunicatorShell>(uri, 0, 1, "BottomBarVisibilityCommunicatorShell", "Can't create BottomBarVisibilityCommunicatorShell");
48− qmlRegisterSingletonType<ApplicationPaths>(uri, 0, 1, "ApplicationPaths", applicationsPathsSingleton);
49}
46}
50
47
51void UtilsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
48void UtilsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
@@ -64,4 +61,9 @@ void UtilsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
64 {
61 {
65 qWarning() << "Failed to register image provider for albumart (unknown error)";
62 qWarning() << "Failed to register image provider for albumart (unknown error)";
66 }
63 }
64+
65+ QDBusConnection::sessionBus().registerService(DBUS_SERVICE);
66+ BottomBarVisibilityCommunicatorShell *bottomBarVisibilityCommunicator = &BottomBarVisibilityCommunicatorShell::instance();
67+ QDBusConnection::sessionBus().registerObject(BOTTOM_BAR_VISIBILITY_COMMUNICATOR_DBUS_PATH, bottomBarVisibilityCommunicator, QDBusConnection::ExportAllContents);
68+ engine->rootContext()->setContextProperty("bottomBarVisibilityCommunicatorShell", bottomBarVisibilityCommunicator);
67}
69}
plugins/Utils/ubuntuwindow.cppdeleted−36
@@ -1,36 +0,0 @@
1−/*
2− * Copyright (C) 2012 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−#include "ubuntuwindow.h"
18−#include <QDebug>
19−
20−
21−UbuntuWindow::UbuntuWindow(QObject *parent)
22− : QObject(parent),
23− m_window(static_cast<QQuickWindow*>(parent))
24−{
25−}
26−
27−int UbuntuWindow::ubuntuSurfaceRole() const
28−{
29− return m_window->property("UbuntuSurfaceRole").toInt();
30−}
31−
32−void UbuntuWindow::setUbuntuSurfaceRole(int ubuntuSurfaceRole)
33−{
34− qDebug() << "setUbuntuSurfaceRole" << ubuntuSurfaceRole;
35− m_window->setProperty("UbuntuSurfaceRole", ubuntuSurfaceRole);
36−}
plugins/Utils/ubuntuwindow.hdeleted−42
@@ -1,42 +0,0 @@
1−/*
2− * Copyright (C) 2012 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−#ifndef UBUNTUWINDOW_H
18−#define UBUNTUWINDOW_H
19−
20−#include <QtCore/QObject>
21−#include <QtQuick/QQuickWindow>
22−
23−class UbuntuWindow : public QObject
24−{
25− Q_OBJECT
26−
27− Q_PROPERTY(int ubuntuSurfaceRole READ ubuntuSurfaceRole WRITE setUbuntuSurfaceRole NOTIFY ubuntuSurfaceRoleChanged)
28−
29−public:
30− explicit UbuntuWindow(QObject *parent = 0);
31−
32− int ubuntuSurfaceRole() const;
33− void setUbuntuSurfaceRole(int ubuntuSurfaceRole);
34−
35−Q_SIGNALS:
36− void ubuntuSurfaceRoleChanged(int);
37−
38−private:
39− QQuickWindow* m_window;
40−};
41−
42−#endif // UBUNTUWINDOW_H
po/ar.po+23−10
@@ -7,8 +7,8 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11−"PO-Revision-Date: 2013-10-20 19:41+0000\n"
11+"PO-Revision-Date: 2013-11-15 12:29+0000\n"
12"Last-Translator: Ibrahim Saed <ibraheem5000@gmail.com>\n"
12"Last-Translator: Ibrahim Saed <ibraheem5000@gmail.com>\n"
13"Language-Team: Arabic <ar@li.org>\n"
13"Language-Team: Arabic <ar@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n % 100 >= "
17"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n % 100 >= "
18"3 && n % 100 <= 10 ? 3 : n % 100 >= 11 && n % 100 <= 99 ? 4 : 5;\n"
18"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"
19+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
20−"X-Generator: Launchpad (build 16807)\n"
20+"X-Generator: Launchpad (build 16831)\n"
21
21
22#: Applications/applications.js:23
22#: Applications/applications.js:23
23msgid "Phone"
23msgid "Phone"
@@ -87,7 +87,7 @@ msgstr "ويكيبيديا"
87msgid "YouTube"
87msgid "YouTube"
88msgstr "يوتيوب"
88msgstr "يوتيوب"
89
89
90−#: Components/EdgeDemoOverlay.qml:149
90+#: Components/EdgeDemoOverlay.qml:151
91msgid "Skip intro"
91msgid "Skip intro"
92msgstr "تخطي المقدمة"
92msgstr "تخطي المقدمة"
93
93
@@ -136,7 +136,7 @@ msgstr ""
136"لقد أتقنت الآن إيماءات الحواف ويمكنك البدء باستخدام الهاتف<br><br>انقر في أي "
136"لقد أتقنت الآن إيماءات الحواف ويمكنك البدء باستخدام الهاتف<br><br>انقر في أي "
137"مكان للبدء"
137"مكان للبدء"
138
138
139−#: Components/PageHeader.qml:341
139+#: Components/PageHeader.qml:345
140msgid "Recent searches"
140msgid "Recent searches"
141msgstr "عمليات البحث الأخيرة"
141msgstr "عمليات البحث الأخيرة"
142
142
@@ -160,7 +160,7 @@ msgstr[3] "%1 تعليقات"
160msgstr[4] "%1 تعليقا"
160msgstr[4] "%1 تعليقا"
161msgstr[5] "%1 تعليق"
161msgstr[5] "%1 تعليق"
162
162
163−#: Dash/Apps/AppPreview.qml:126
163+#: Dash/Apps/AppPreview.qml:135
164msgid "Rate this"
164msgid "Rate this"
165msgstr "قيّم ذلك"
165msgstr "قيّم ذلك"
166
166
@@ -180,7 +180,7 @@ msgstr "أرسل"
180msgid "Comments:"
180msgid "Comments:"
181msgstr "التعليقات:"
181msgstr "التعليقات:"
182
182
183−#: Greeter/Lockscreen.qml:142
183+#: Greeter/Lockscreen.qml:146
184msgid "Emergency Call"
184msgid "Emergency Call"
185msgstr "مكالمة طوارئ"
185msgstr "مكالمة طوارئ"
186
186
@@ -213,11 +213,24 @@ msgstr "تكلم الآن..."
213msgid "Speaking..."
213msgid "Speaking..."
214msgstr "تتكلم الآن..."
214msgstr "تتكلم الآن..."
215
215
216+#: Notifications/NotificationMenuItemFactory.qml:89
217+msgid "Show password"
218+msgstr "عرض كلمة السر"
219+
216#: Panel/SearchIndicator.qml:27
220#: Panel/SearchIndicator.qml:27
217msgid "Search"
221msgid "Search"
218msgstr "ابحث"
222msgstr "ابحث"
219
223
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
221msgid "Sorry, there is nothing that matches your search."
234msgid "Sorry, there is nothing that matches your search."
222msgstr "عذراً، لا يوجد ما يطابق بحثك."
235msgstr "عذراً، لا يوجد ما يطابق بحثك."
223
236
@@ -225,7 +238,7 @@ msgstr "عذراً، لا يوجد ما يطابق بحثك."
225msgid "All"
238msgid "All"
226msgstr "الكل"
239msgstr "الكل"
227
240
228−#: Shell.qml:438
241+#: Shell.qml:441
229#, qt-format
242#, qt-format
230msgid "Please enter %1"
243msgid "Please enter %1"
231msgstr "من فضلك أدخِل %1"
244msgstr "من فضلك أدخِل %1"
po/ast.po+22−30
@@ -7,7 +7,7 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity8\n"
8"Project-Id-Version: unity8\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-10-03 14:02+0000\n"
11"PO-Revision-Date: 2013-10-03 14:02+0000\n"
12"Last-Translator: ivarela <ivarela@ubuntu.com>\n"
12"Last-Translator: ivarela <ivarela@ubuntu.com>\n"
13"Language-Team: Asturian <ast@li.org>\n"
13"Language-Team: Asturian <ast@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Wikipedia"
86msgid "YouTube"
86msgid "YouTube"
87msgstr "YouTube"
87msgstr "YouTube"
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr "Omitir la intro"
91msgstr "Omitir la intro"
92
92
@@ -136,7 +136,7 @@ msgstr ""
136"Agora domines los xestos de berbesos y pues usar el teléfonu<br><br>Toca la "
136"Agora domines los xestos de berbesos y pues usar el teléfonu<br><br>Toca la "
137"pantalla pa entamar"
137"pantalla pa entamar"
138
138
139−#: Components/PageHeader.qml:341
139+#: Components/PageHeader.qml:345
140msgid "Recent searches"
140msgid "Recent searches"
141msgstr "Busques recientes"
141msgstr "Busques recientes"
142
142
@@ -156,7 +156,7 @@ msgid_plural "%1 reviews"
156msgstr[0] "%1 reseña"
156msgstr[0] "%1 reseña"
157msgstr[1] "%1 reseñes"
157msgstr[1] "%1 reseñes"
158
158
159−#: Dash/Apps/AppPreview.qml:126
159+#: Dash/Apps/AppPreview.qml:135
160msgid "Rate this"
160msgid "Rate this"
161msgstr "Valorar esto"
161msgstr "Valorar esto"
162
162
@@ -176,7 +176,7 @@ msgstr "Unviar"
176msgid "Comments:"
176msgid "Comments:"
177msgstr "Comentarios:"
177msgstr "Comentarios:"
178
178
179−#: Greeter/Lockscreen.qml:142
179+#: Greeter/Lockscreen.qml:146
180msgid "Emergency Call"
180msgid "Emergency Call"
181msgstr "Llamada d'emerxencia"
181msgstr "Llamada d'emerxencia"
182
182
@@ -209,11 +209,24 @@ msgstr "Fala agora…"
209msgid "Speaking..."
209msgid "Speaking..."
210msgstr "Falando…"
210msgstr "Falando…"
211
211
212+#: Notifications/NotificationMenuItemFactory.qml:89
213+msgid "Show password"
214+msgstr ""
215+
212#: Panel/SearchIndicator.qml:27
216#: Panel/SearchIndicator.qml:27
213msgid "Search"
217msgid "Search"
214msgstr "Guetar"
218msgstr "Guetar"
215
219
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
217msgid "Sorry, there is nothing that matches your search."
230msgid "Sorry, there is nothing that matches your search."
218msgstr "Sentímoslo, nun hai res que concase cola gueta"
231msgstr "Sentímoslo, nun hai res que concase cola gueta"
219
232
@@ -221,28 +234,7 @@ msgstr "Sentímoslo, nun hai res que concase cola gueta"
221msgid "All"
234msgid "All"
222msgstr "Too"
235msgstr "Too"
223
236
224−#: Shell.qml:438
237+#: Shell.qml:441
225#, qt-format
238#, qt-format
226msgid "Please enter %1"
239msgid "Please enter %1"
227msgstr "Introduz %1"
240msgstr "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 ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-06-26 23:48+0000\n"
11"PO-Revision-Date: 2013-06-26 23:48+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Azerbaijani <az@li.org>\n"
13"Language-Team: Azerbaijani <az@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
86msgid "YouTube"
86msgid "YouTube"
87msgstr ""
87msgstr ""
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr "Son axtarışlar"
137msgstr "Son axtarışlar"
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr ""
172msgid "Comments:"
172msgid "Comments:"
173msgstr ""
173msgstr ""
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr "Söyləyin..."
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr "Söylənilir..."
206msgstr "Söylənilir..."
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr "Axtar"
214msgstr "Axtar"
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr "Bağışlayın, amma axtarışınıza heç bir nəticə uyğun gəlmir."
227msgstr "Bağışlayın, amma axtarışınıza heç bir nəticə uyğun gəlmir."
215
228
@@ -217,13 +230,7 @@ msgstr "Bağışlayın, amma axtarışınıza heç bir nəticə uyğun gəlmir."
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr ""
236msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Musiqi"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Videolar"
po/bg.po+22−21
@@ -7,7 +7,7 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-06-27 00:06+0000\n"
11"PO-Revision-Date: 2013-06-27 00:06+0000\n"
12"Last-Translator: Miroslav E. Hadzhiev (Хаджиев) "
12"Last-Translator: Miroslav E. Hadzhiev (Хаджиев) "
13"<miroslav.hadzhiev@gmail.com>\n"
13"<miroslav.hadzhiev@gmail.com>\n"
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
20−"X-Generator: Launchpad (build 16799)\n"
20+"X-Generator: Launchpad (build 16831)\n"
21
21
22#: Applications/applications.js:23
22#: Applications/applications.js:23
23msgid "Phone"
23msgid "Phone"
@@ -87,7 +87,7 @@ msgstr "Уикипедия"
87msgid "YouTube"
87msgid "YouTube"
88msgstr "YouTube"
88msgstr "YouTube"
89
89
90−#: Components/EdgeDemoOverlay.qml:149
90+#: Components/EdgeDemoOverlay.qml:151
91msgid "Skip intro"
91msgid "Skip intro"
92msgstr ""
92msgstr ""
93
93
@@ -133,7 +133,7 @@ msgid ""
133"phone<br><br>Tap anywhere to start"
133"phone<br><br>Tap anywhere to start"
134msgstr ""
134msgstr ""
135
135
136−#: Components/PageHeader.qml:341
136+#: Components/PageHeader.qml:345
137msgid "Recent searches"
137msgid "Recent searches"
138msgstr "Скорошни търсения"
138msgstr "Скорошни търсения"
139
139
@@ -153,7 +153,7 @@ msgid_plural "%1 reviews"
153msgstr[0] ""
153msgstr[0] ""
154msgstr[1] ""
154msgstr[1] ""
155
155
156−#: Dash/Apps/AppPreview.qml:126
156+#: Dash/Apps/AppPreview.qml:135
157msgid "Rate this"
157msgid "Rate this"
158msgstr ""
158msgstr ""
159
159
@@ -173,7 +173,7 @@ msgstr ""
173msgid "Comments:"
173msgid "Comments:"
174msgstr ""
174msgstr ""
175
175
176−#: Greeter/Lockscreen.qml:142
176+#: Greeter/Lockscreen.qml:146
177msgid "Emergency Call"
177msgid "Emergency Call"
178msgstr ""
178msgstr ""
179
179
@@ -206,11 +206,24 @@ msgstr ""
206msgid "Speaking..."
206msgid "Speaking..."
207msgstr ""
207msgstr ""
208
208
209+#: Notifications/NotificationMenuItemFactory.qml:89
210+msgid "Show password"
211+msgstr ""
212+
209#: Panel/SearchIndicator.qml:27
213#: Panel/SearchIndicator.qml:27
210msgid "Search"
214msgid "Search"
211msgstr "Търсене"
215msgstr "Търсене"
212
216
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
214msgid "Sorry, there is nothing that matches your search."
227msgid "Sorry, there is nothing that matches your search."
215msgstr "Съжаляваме, няма нищо, което да отговаря на вашето търсене."
228msgstr "Съжаляваме, няма нищо, което да отговаря на вашето търсене."
216
229
@@ -218,19 +231,7 @@ msgstr "Съжаляваме, няма нищо, което да отговар
218msgid "All"
231msgid "All"
219msgstr ""
232msgstr ""
220
233
221−#: Shell.qml:438
234+#: Shell.qml:441
222#, qt-format
235#, qt-format
223msgid "Please enter %1"
236msgid "Please enter %1"
224msgstr ""
237msgstr ""
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 ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-09-28 07:38+0000\n"
11"PO-Revision-Date: 2013-09-28 07:38+0000\n"
12"Last-Translator: David Planella <david.planella@ubuntu.com>\n"
12"Last-Translator: David Planella <david.planella@ubuntu.com>\n"
13"Language-Team: Catalan <ca@li.org>\n"
13"Language-Team: Catalan <ca@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Viquipèdia"
86msgid "YouTube"
86msgid "YouTube"
87msgstr "YouTube"
87msgstr "YouTube"
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr "Omet la introducció"
91msgstr "Omet la introducció"
92
92
@@ -138,7 +138,7 @@ msgid ""
138"phone<br><br>Tap anywhere to start"
138"phone<br><br>Tap anywhere to start"
139msgstr ""
139msgstr ""
140
140
141−#: Components/PageHeader.qml:341
141+#: Components/PageHeader.qml:345
142msgid "Recent searches"
142msgid "Recent searches"
143msgstr "Cerques recents"
143msgstr "Cerques recents"
144
144
@@ -158,7 +158,7 @@ msgid_plural "%1 reviews"
158msgstr[0] "%1 ressenya"
158msgstr[0] "%1 ressenya"
159msgstr[1] "%1 ressenyes"
159msgstr[1] "%1 ressenyes"
160
160
161−#: Dash/Apps/AppPreview.qml:126
161+#: Dash/Apps/AppPreview.qml:135
162msgid "Rate this"
162msgid "Rate this"
163msgstr ""
163msgstr ""
164
164
@@ -178,7 +178,7 @@ msgstr "Envia"
178msgid "Comments:"
178msgid "Comments:"
179msgstr "Comentaris:"
179msgstr "Comentaris:"
180
180
181−#: Greeter/Lockscreen.qml:142
181+#: Greeter/Lockscreen.qml:146
182msgid "Emergency Call"
182msgid "Emergency Call"
183msgstr "Trucada d'emergència"
183msgstr "Trucada d'emergència"
184
184
@@ -211,11 +211,24 @@ msgstr "Parleu..."
211msgid "Speaking..."
211msgid "Speaking..."
212msgstr "S'està parlant..."
212msgstr "S'està parlant..."
213
213
214+#: Notifications/NotificationMenuItemFactory.qml:89
215+msgid "Show password"
216+msgstr ""
217+
214#: Panel/SearchIndicator.qml:27
218#: Panel/SearchIndicator.qml:27
215msgid "Search"
219msgid "Search"
216msgstr "Cerca"
220msgstr "Cerca"
217
221
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
219msgid "Sorry, there is nothing that matches your search."
232msgid "Sorry, there is nothing that matches your search."
220msgstr "No hi ha res que coincideixi amb la cerca"
233msgstr "No hi ha res que coincideixi amb la cerca"
221
234
@@ -223,28 +236,7 @@ msgstr "No hi ha res que coincideixi amb la cerca"
223msgid "All"
236msgid "All"
224msgstr ""
237msgstr ""
225
238
226−#: Shell.qml:438
239+#: Shell.qml:441
227#, qt-format
240#, qt-format
228msgid "Please enter %1"
241msgid "Please enter %1"
229msgstr "Introduïu %1"
242msgstr "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 ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity8\n"
8"Project-Id-Version: unity8\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-10-08 08:09+0000\n"
11"PO-Revision-Date: 2013-10-08 08:09+0000\n"
12"Last-Translator: Tadeáš Pařík <tadeas.parik@gmail.com>\n"
12"Last-Translator: Tadeáš Pařík <tadeas.parik@gmail.com>\n"
13"Language-Team: Czech <cs@li.org>\n"
13"Language-Team: Czech <cs@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
17"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"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Wikipedie"
86msgid "YouTube"
86msgid "YouTube"
87msgstr "YouTube"
87msgstr "YouTube"
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr "Přeskočit intro"
91msgstr "Přeskočit intro"
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr "Poslední vyhledávání"
137msgstr "Poslední vyhledávání"
138
138
@@ -153,7 +153,7 @@ msgstr[0] "%1 recenze"
153msgstr[1] "%1 recenze"
153msgstr[1] "%1 recenze"
154msgstr[2] "%1 recenzí"
154msgstr[2] "%1 recenzí"
155
155
156−#: Dash/Apps/AppPreview.qml:126
156+#: Dash/Apps/AppPreview.qml:135
157msgid "Rate this"
157msgid "Rate this"
158msgstr "Ohodnoťte to"
158msgstr "Ohodnoťte to"
159
159
@@ -173,7 +173,7 @@ msgstr "Odeslat"
173msgid "Comments:"
173msgid "Comments:"
174msgstr "Komentáře:"
174msgstr "Komentáře:"
175
175
176−#: Greeter/Lockscreen.qml:142
176+#: Greeter/Lockscreen.qml:146
177msgid "Emergency Call"
177msgid "Emergency Call"
178msgstr "Tísňové volání"
178msgstr "Tísňové volání"
179
179
@@ -206,11 +206,24 @@ msgstr "Mluvte..."
206msgid "Speaking..."
206msgid "Speaking..."
207msgstr "Mluvte..."
207msgstr "Mluvte..."
208
208
209+#: Notifications/NotificationMenuItemFactory.qml:89
210+msgid "Show password"
211+msgstr ""
212+
209#: Panel/SearchIndicator.qml:27
213#: Panel/SearchIndicator.qml:27
210msgid "Search"
214msgid "Search"
211msgstr "Hledat"
215msgstr "Hledat"
212
216
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
214msgid "Sorry, there is nothing that matches your search."
227msgid "Sorry, there is nothing that matches your search."
215msgstr "Je nám líto, ale nic neodpovídá zadání"
228msgstr "Je nám líto, ale nic neodpovídá zadání"
216
229
@@ -218,22 +231,7 @@ msgstr "Je nám líto, ale nic neodpovídá zadání"
218msgid "All"
231msgid "All"
219msgstr "Vše"
232msgstr "Vše"
220
233
221−#: Shell.qml:438
234+#: Shell.qml:441
222#, qt-format
235#, qt-format
223msgid "Please enter %1"
236msgid "Please enter %1"
224msgstr "Zadejte prosím %1"
237msgstr "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 ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-10-18 12:26+0000\n"
11"PO-Revision-Date: 2013-10-18 12:26+0000\n"
12"Last-Translator: Phillip Sz <Unknown>\n"
12"Last-Translator: Phillip Sz <Unknown>\n"
13"Language-Team: German <de@li.org>\n"
13"Language-Team: German <de@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-19 05:30+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16807)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Wikipedia"
86msgid "YouTube"
86msgid "YouTube"
87msgstr "YouTube"
87msgstr "YouTube"
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr "Überspringe Einführung"
91msgstr "Überspringe Einführung"
92
92
@@ -136,7 +136,7 @@ msgstr ""
136"Sie haben nun die Einführung abgeschlossen und können Ihr Gerät nun "
136"Sie haben nun die Einführung abgeschlossen und können Ihr Gerät nun "
137"verwenden<br><br>Antippen um zu starten"
137"verwenden<br><br>Antippen um zu starten"
138
138
139−#: Components/PageHeader.qml:341
139+#: Components/PageHeader.qml:345
140msgid "Recent searches"
140msgid "Recent searches"
141msgstr "Letzte Suchbegriffe"
141msgstr "Letzte Suchbegriffe"
142
142
@@ -156,7 +156,7 @@ msgid_plural "%1 reviews"
156msgstr[0] "%1 Bewertung"
156msgstr[0] "%1 Bewertung"
157msgstr[1] "%1 Bewertungen"
157msgstr[1] "%1 Bewertungen"
158
158
159−#: Dash/Apps/AppPreview.qml:126
159+#: Dash/Apps/AppPreview.qml:135
160msgid "Rate this"
160msgid "Rate this"
161msgstr "Bewerten"
161msgstr "Bewerten"
162
162
@@ -176,7 +176,7 @@ msgstr "Senden"
176msgid "Comments:"
176msgid "Comments:"
177msgstr "Kommentare:"
177msgstr "Kommentare:"
178
178
179−#: Greeter/Lockscreen.qml:142
179+#: Greeter/Lockscreen.qml:146
180msgid "Emergency Call"
180msgid "Emergency Call"
181msgstr "Notruf"
181msgstr "Notruf"
182
182
@@ -209,11 +209,24 @@ msgstr "Sprechen Sie jetzt …"
209msgid "Speaking..."
209msgid "Speaking..."
210msgstr "Sie sprechen …"
210msgstr "Sie sprechen …"
211
211
212+#: Notifications/NotificationMenuItemFactory.qml:89
213+msgid "Show password"
214+msgstr ""
215+
212#: Panel/SearchIndicator.qml:27
216#: Panel/SearchIndicator.qml:27
213msgid "Search"
217msgid "Search"
214msgstr "Suchen"
218msgstr "Suchen"
215
219
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
217msgid "Sorry, there is nothing that matches your search."
230msgid "Sorry, there is nothing that matches your search."
218msgstr "Entschuldigung, es wurden keine Treffer erzielt."
231msgstr "Entschuldigung, es wurden keine Treffer erzielt."
219
232
@@ -221,7 +234,7 @@ msgstr "Entschuldigung, es wurden keine Treffer erzielt."
221msgid "All"
234msgid "All"
222msgstr "Alle"
235msgstr "Alle"
223
236
224−#: Shell.qml:438
237+#: Shell.qml:441
225#, qt-format
238#, qt-format
226msgid "Please enter %1"
239msgid "Please enter %1"
227msgstr "Bitte geben Sie %1 ein"
240msgstr "Bitte geben Sie %1 ein"
po/el.po+22−15
@@ -7,7 +7,7 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-06-27 00:53+0000\n"
11"PO-Revision-Date: 2013-06-27 00:53+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Greek <el@li.org>\n"
13"Language-Team: Greek <el@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
86msgid "YouTube"
86msgid "YouTube"
87msgstr ""
87msgstr ""
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr "Πρόσφατες αναζητήσεις"
137msgstr "Πρόσφατες αναζητήσεις"
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr ""
172msgid "Comments:"
172msgid "Comments:"
173msgstr ""
173msgstr ""
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr "Μιλήστε τώρα..."
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr "Ομιλία..."
206msgstr "Ομιλία..."
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr "Αναζήτηση"
214msgstr "Αναζήτηση"
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr "Λυπούμαστε, δεν υπάρχει τίποτα που να ταιριάζει στην αναζήτησή σας."
227msgstr "Λυπούμαστε, δεν υπάρχει τίποτα που να ταιριάζει στην αναζήτησή σας."
215
228
@@ -217,13 +230,7 @@ msgstr "Λυπούμαστε, δεν υπάρχει τίποτα που να τ
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr ""
236msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Μουσική"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Βίντεο"
po/en_AU.po+22−30
@@ -7,7 +7,7 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-09-28 07:46+0000\n"
11"PO-Revision-Date: 2013-09-28 07:46+0000\n"
12"Last-Translator: Jared Norris <jarednorris@ubuntu.com>\n"
12"Last-Translator: Jared Norris <jarednorris@ubuntu.com>\n"
13"Language-Team: English (Australia) <en_AU@li.org>\n"
13"Language-Team: English (Australia) <en_AU@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Wikipedia"
86msgid "YouTube"
86msgid "YouTube"
87msgstr "YouTube"
87msgstr "YouTube"
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr "Skip intro"
91msgstr "Skip intro"
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr "Recent searches"
137msgstr "Recent searches"
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] "%1 review"
152msgstr[0] "%1 review"
153msgstr[1] "%1 reviews"
153msgstr[1] "%1 reviews"
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr "Rate this"
157msgstr "Rate this"
158
158
@@ -172,7 +172,7 @@ msgstr "Send"
172msgid "Comments:"
172msgid "Comments:"
173msgstr "Comments:"
173msgstr "Comments:"
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr "Emergency Call"
177msgstr "Emergency Call"
178
178
@@ -205,11 +205,24 @@ msgstr "Speak Now..."
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr "Speaking..."
206msgstr "Speaking..."
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr "Search"
214msgstr "Search"
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr "Sorry, there is nothing that matches your search."
227msgstr "Sorry, there is nothing that matches your search."
215
228
@@ -217,28 +230,7 @@ msgstr "Sorry, there is nothing that matches your search."
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr "Please enter %1"
236msgstr "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 ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-06-27 08:53+0000\n"
11"PO-Revision-Date: 2013-06-27 08:53+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: English (United Kingdom) <en_GB@li.org>\n"
13"Language-Team: English (United Kingdom) <en_GB@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Wikipedia"
86msgid "YouTube"
86msgid "YouTube"
87msgstr "YouTube"
87msgstr "YouTube"
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr "Recent searches"
137msgstr "Recent searches"
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr ""
172msgid "Comments:"
172msgid "Comments:"
173msgstr ""
173msgstr ""
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr "Speak Now..."
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr "Speaking..."
206msgstr "Speaking..."
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr "Search"
214msgstr "Search"
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr "Sorry, there is nothing that matches your search."
227msgstr "Sorry, there is nothing that matches your search."
215
228
@@ -217,28 +230,7 @@ msgstr "Sorry, there is nothing that matches your search."
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr "Please enter %1"
236msgstr "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 ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-06-26 22:35+0000\n"
11"PO-Revision-Date: 2013-06-26 22:35+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Esperanto <eo@li.org>\n"
13"Language-Team: Esperanto <eo@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
86msgid "YouTube"
86msgid "YouTube"
87msgstr ""
87msgstr ""
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr ""
137msgstr ""
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr ""
172msgid "Comments:"
172msgid "Comments:"
173msgstr ""
173msgstr ""
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr ""
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr ""
206msgstr ""
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr ""
214msgstr ""
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr ""
227msgstr ""
215
228
@@ -217,7 +230,7 @@ msgstr ""
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr ""
236msgstr ""
po/es.po+23−31
@@ -7,16 +7,16 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11−"PO-Revision-Date: 2013-10-02 04:59+0000\n"
11+"PO-Revision-Date: 2013-11-20 08:46+0000\n"
12"Last-Translator: Adolfo Jayme Barrientos <fitoschido@gmail.com>\n"
12"Last-Translator: Adolfo Jayme Barrientos <fitoschido@gmail.com>\n"
13"Language-Team: Spanish <es@li.org>\n"
13"Language-Team: Spanish <es@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-21 06:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Wikipedia"
86msgid "YouTube"
86msgid "YouTube"
87msgstr "YouTube"
87msgstr "YouTube"
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr "Omitir la introducción"
91msgstr "Omitir la introducción"
92
92
@@ -136,7 +136,7 @@ msgstr ""
136"Ahora domina los gestos de bordes y puede usar el teléfono<br><br>Toque la "
136"Ahora domina los gestos de bordes y puede usar el teléfono<br><br>Toque la "
137"pantalla para comenzar"
137"pantalla para comenzar"
138
138
139−#: Components/PageHeader.qml:341
139+#: Components/PageHeader.qml:345
140msgid "Recent searches"
140msgid "Recent searches"
141msgstr "Búsquedas recientes"
141msgstr "Búsquedas recientes"
142
142
@@ -156,7 +156,7 @@ msgid_plural "%1 reviews"
156msgstr[0] "%1 reseña"
156msgstr[0] "%1 reseña"
157msgstr[1] "%1 reseñas"
157msgstr[1] "%1 reseñas"
158
158
159−#: Dash/Apps/AppPreview.qml:126
159+#: Dash/Apps/AppPreview.qml:135
160msgid "Rate this"
160msgid "Rate this"
161msgstr "Valorar esto"
161msgstr "Valorar esto"
162
162
@@ -176,7 +176,7 @@ msgstr "Enviar"
176msgid "Comments:"
176msgid "Comments:"
177msgstr "Comentarios:"
177msgstr "Comentarios:"
178
178
179−#: Greeter/Lockscreen.qml:142
179+#: Greeter/Lockscreen.qml:146
180msgid "Emergency Call"
180msgid "Emergency Call"
181msgstr "Llamada de emergencia"
181msgstr "Llamada de emergencia"
182
182
@@ -209,11 +209,24 @@ msgstr "Hable ahora…"
209msgid "Speaking..."
209msgid "Speaking..."
210msgstr "Hablando…"
210msgstr "Hablando…"
211
211
212+#: Notifications/NotificationMenuItemFactory.qml:89
213+msgid "Show password"
214+msgstr "Mostrar contraseña"
215+
212#: Panel/SearchIndicator.qml:27
216#: Panel/SearchIndicator.qml:27
213msgid "Search"
217msgid "Search"
214msgstr "Buscar"
218msgstr "Buscar"
215
219
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 "Mantener en el lanzador"
224+
225+#: plugins/Unity/Launcher/launcheritem.cpp:73
226+msgid "Unlock from Launcher"
227+msgstr "No mantener en el lanzador"
228+
229+#: plugins/Unity/scope.cpp:408
217msgid "Sorry, there is nothing that matches your search."
230msgid "Sorry, there is nothing that matches your search."
218msgstr "No hay nada que coincida con su búsqueda."
231msgstr "No hay nada que coincida con su búsqueda."
219
232
@@ -221,28 +234,7 @@ msgstr "No hay nada que coincida con su búsqueda."
221msgid "All"
234msgid "All"
222msgstr "Todo"
235msgstr "Todo"
223
236
224−#: Shell.qml:438
237+#: Shell.qml:441
225#, qt-format
238#, qt-format
226msgid "Please enter %1"
239msgid "Please enter %1"
227msgstr "Introduzca %1"
240msgstr "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 ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity8\n"
8"Project-Id-Version: unity8\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-10-31 19:02+0000\n"
11"PO-Revision-Date: 2013-10-31 19:02+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Persian <fa@li.org>\n"
13"Language-Team: Persian <fa@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-11-01 06:44+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16820)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
86msgid "YouTube"
86msgid "YouTube"
87msgstr ""
87msgstr ""
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr ""
137msgstr ""
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr ""
172msgid "Comments:"
172msgid "Comments:"
173msgstr ""
173msgstr ""
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr ""
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr ""
206msgstr ""
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr ""
214msgstr ""
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr ""
227msgstr ""
215
228
@@ -217,7 +230,7 @@ msgstr ""
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr ""
236msgstr ""
po/fi.po+23−31
@@ -7,16 +7,16 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11−"PO-Revision-Date: 2013-10-03 09:21+0000\n"
11+"PO-Revision-Date: 2013-11-20 08:09+0000\n"
12"Last-Translator: Jiri Grönroos <Unknown>\n"
12"Last-Translator: Jiri Grönroos <Unknown>\n"
13"Language-Team: Finnish <fi@li.org>\n"
13"Language-Team: Finnish <fi@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-21 06:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Wikipedia"
86msgid "YouTube"
86msgid "YouTube"
87msgstr "YouTube"
87msgstr "YouTube"
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr "Ohita esittely"
91msgstr "Ohita esittely"
92
92
@@ -134,7 +134,7 @@ msgstr ""
134"Hallitset nyt reunaeleet, joten voit aloittaa puhelimen "
134"Hallitset nyt reunaeleet, joten voit aloittaa puhelimen "
135"käytön<br><br>Napauta missä tahansa aloittaaksesi"
135"käytön<br><br>Napauta missä tahansa aloittaaksesi"
136
136
137−#: Components/PageHeader.qml:341
137+#: Components/PageHeader.qml:345
138msgid "Recent searches"
138msgid "Recent searches"
139msgstr "Viimeisimmät haut"
139msgstr "Viimeisimmät haut"
140
140
@@ -154,7 +154,7 @@ msgid_plural "%1 reviews"
154msgstr[0] "%1 arvostelu"
154msgstr[0] "%1 arvostelu"
155msgstr[1] "%1 arvostelua"
155msgstr[1] "%1 arvostelua"
156
156
157−#: Dash/Apps/AppPreview.qml:126
157+#: Dash/Apps/AppPreview.qml:135
158msgid "Rate this"
158msgid "Rate this"
159msgstr "Arvioi tämä"
159msgstr "Arvioi tämä"
160
160
@@ -174,7 +174,7 @@ msgstr "Lähetä"
174msgid "Comments:"
174msgid "Comments:"
175msgstr "Kommentit:"
175msgstr "Kommentit:"
176
176
177−#: Greeter/Lockscreen.qml:142
177+#: Greeter/Lockscreen.qml:146
178msgid "Emergency Call"
178msgid "Emergency Call"
179msgstr "Hätäpuhelu"
179msgstr "Hätäpuhelu"
180
180
@@ -207,11 +207,24 @@ msgstr "Puhu nyt..."
207msgid "Speaking..."
207msgid "Speaking..."
208msgstr "Puhutaan..."
208msgstr "Puhutaan..."
209
209
210+#: Notifications/NotificationMenuItemFactory.qml:89
211+msgid "Show password"
212+msgstr "Näytä salasana"
213+
210#: Panel/SearchIndicator.qml:27
214#: Panel/SearchIndicator.qml:27
211msgid "Search"
215msgid "Search"
212msgstr "Hae"
216msgstr "Hae"
213
217
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 "Kiinnitä käynnistimeen"
222+
223+#: plugins/Unity/Launcher/launcheritem.cpp:73
224+msgid "Unlock from Launcher"
225+msgstr "Poista käynnistimestä"
226+
227+#: plugins/Unity/scope.cpp:408
215msgid "Sorry, there is nothing that matches your search."
228msgid "Sorry, there is nothing that matches your search."
216msgstr "Hakuun täsmääviä tuloksia ei löydy."
229msgstr "Hakuun täsmääviä tuloksia ei löydy."
217
230
@@ -219,28 +232,7 @@ msgstr "Hakuun täsmääviä tuloksia ei löydy."
219msgid "All"
232msgid "All"
220msgstr "Kaikki"
233msgstr "Kaikki"
221
234
222−#: Shell.qml:438
235+#: Shell.qml:441
223#, qt-format
236#, qt-format
224msgid "Please enter %1"
237msgid "Please enter %1"
225msgstr "Kirjoita %1"
238msgstr "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 ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-10-01 15:13+0000\n"
11"PO-Revision-Date: 2013-10-01 15:13+0000\n"
12"Last-Translator: Jógvan Olsen <jeggy@jebster.net>\n"
12"Last-Translator: Jógvan Olsen <jeggy@jebster.net>\n"
13"Language-Team: Faroese <fo@li.org>\n"
13"Language-Team: Faroese <fo@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
86msgid "YouTube"
86msgid "YouTube"
87msgstr ""
87msgstr ""
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr ""
137msgstr ""
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr ""
172msgid "Comments:"
172msgid "Comments:"
173msgstr ""
173msgstr ""
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr "Snakka nú..."
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr "Snakkar..."
206msgstr "Snakkar..."
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr "Leita"
214msgstr "Leita"
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr "Tíanverri er tað einki sum hóskar til tína leiting."
227msgstr "Tíanverri er tað einki sum hóskar til tína leiting."
215
228
@@ -217,13 +230,7 @@ msgstr "Tíanverri er tað einki sum hóskar til tína leiting."
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr ""
236msgstr ""
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 ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-06-27 03:21+0000\n"
11"PO-Revision-Date: 2013-06-27 03:21+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: French <fr@li.org>\n"
13"Language-Team: French <fr@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n > 1;\n"
17"Plural-Forms: nplurals=2; plural=n > 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
86msgid "YouTube"
86msgid "YouTube"
87msgstr ""
87msgstr ""
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr ""
137msgstr ""
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr ""
172msgid "Comments:"
172msgid "Comments:"
173msgstr ""
173msgstr ""
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr ""
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr ""
206msgstr ""
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr ""
214msgstr ""
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr ""
227msgstr ""
215
228
@@ -217,13 +230,7 @@ msgstr ""
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr ""
236msgstr ""
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 ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity8\n"
8"Project-Id-Version: unity8\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-09-30 10:34+0000\n"
11"PO-Revision-Date: 2013-09-30 10:34+0000\n"
12"Last-Translator: Akerbeltz <fios@akerbeltz.org>\n"
12"Last-Translator: Akerbeltz <fios@akerbeltz.org>\n"
13"Language-Team: Gaelic; Scottish <gd@li.org>\n"
13"Language-Team: Gaelic; Scottish <gd@li.org>\n"
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : "
17"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : "
18"(n > 2 && n < 20) ? 2 : 3;\n"
18"(n > 2 && n < 20) ? 2 : 3;\n"
19−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
20−"X-Generator: Launchpad (build 16799)\n"
20+"X-Generator: Launchpad (build 16831)\n"
21
21
22#: Applications/applications.js:23
22#: Applications/applications.js:23
23msgid "Phone"
23msgid "Phone"
@@ -87,7 +87,7 @@ msgstr "An Uicipeid"
87msgid "YouTube"
87msgid "YouTube"
88msgstr "YouTube"
88msgstr "YouTube"
89
89
90−#: Components/EdgeDemoOverlay.qml:149
90+#: Components/EdgeDemoOverlay.qml:151
91msgid "Skip intro"
91msgid "Skip intro"
92msgstr "Gearr leum thairis air an ro-ràdh"
92msgstr "Gearr leum thairis air an ro-ràdh"
93
93
@@ -139,7 +139,7 @@ msgid ""
139"phone<br><br>Tap anywhere to start"
139"phone<br><br>Tap anywhere to start"
140msgstr ""
140msgstr ""
141
141
142−#: Components/PageHeader.qml:341
142+#: Components/PageHeader.qml:345
143msgid "Recent searches"
143msgid "Recent searches"
144msgstr "Na lorg thu o chionn goirid"
144msgstr "Na lorg thu o chionn goirid"
145
145
@@ -161,7 +161,7 @@ msgstr[1] "%1 lèirmheas"
161msgstr[2] "%1 lèirmheasan"
161msgstr[2] "%1 lèirmheasan"
162msgstr[3] "%1 lèirmheas"
162msgstr[3] "%1 lèirmheas"
163
163
164−#: Dash/Apps/AppPreview.qml:126
164+#: Dash/Apps/AppPreview.qml:135
165msgid "Rate this"
165msgid "Rate this"
166msgstr "Rangaich seo"
166msgstr "Rangaich seo"
167
167
@@ -181,7 +181,7 @@ msgstr "Cuir"
181msgid "Comments:"
181msgid "Comments:"
182msgstr "Beachdan"
182msgstr "Beachdan"
183
183
184−#: Greeter/Lockscreen.qml:142
184+#: Greeter/Lockscreen.qml:146
185msgid "Emergency Call"
185msgid "Emergency Call"
186msgstr "Gairm èiginn"
186msgstr "Gairm èiginn"
187
187
@@ -214,11 +214,24 @@ msgstr "Can rud a-nis..."
214msgid "Speaking..."
214msgid "Speaking..."
215msgstr "A' bruidhinn..."
215msgstr "A' bruidhinn..."
216
216
217+#: Notifications/NotificationMenuItemFactory.qml:89
218+msgid "Show password"
219+msgstr ""
220+
217#: Panel/SearchIndicator.qml:27
221#: Panel/SearchIndicator.qml:27
218msgid "Search"
222msgid "Search"
219msgstr "Lorg"
223msgstr "Lorg"
220
224
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
222msgid "Sorry, there is nothing that matches your search."
235msgid "Sorry, there is nothing that matches your search."
223msgstr "Tha sinn duilich ach chan eil dad a' freagairt ris na lorg thu."
236msgstr "Tha sinn duilich ach chan eil dad a' freagairt ris na lorg thu."
224
237
@@ -226,28 +239,7 @@ msgstr "Tha sinn duilich ach chan eil dad a' freagairt ris na lorg thu."
226msgid "All"
239msgid "All"
227msgstr ""
240msgstr ""
228
241
229−#: Shell.qml:438
242+#: Shell.qml:441
230#, qt-format
243#, qt-format
231msgid "Please enter %1"
244msgid "Please enter %1"
232msgstr "Cuir a-steach %1"
245msgstr "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 ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-10-03 18:49+0000\n"
11"PO-Revision-Date: 2013-10-03 18:49+0000\n"
12"Last-Translator: Marcos Lans <Unknown>\n"
12"Last-Translator: Marcos Lans <Unknown>\n"
13"Language-Team: Galician <gl@li.org>\n"
13"Language-Team: Galician <gl@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Wikipedia"
86msgid "YouTube"
86msgid "YouTube"
87msgstr "YouTube"
87msgstr "YouTube"
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr "Saltar introdución"
91msgstr "Saltar introdución"
92
92
@@ -134,7 +134,7 @@ msgstr ""
134"Xa domina os xestos desde os bordos e pode comezar a usar o "
134"Xa domina os xestos desde os bordos e pode comezar a usar o "
135"móbil<br><br>Toque en calquera sitio para comezar"
135"móbil<br><br>Toque en calquera sitio para comezar"
136
136
137−#: Components/PageHeader.qml:341
137+#: Components/PageHeader.qml:345
138msgid "Recent searches"
138msgid "Recent searches"
139msgstr "Buscas recentes"
139msgstr "Buscas recentes"
140
140
@@ -154,7 +154,7 @@ msgid_plural "%1 reviews"
154msgstr[0] "%1 opinión"
154msgstr[0] "%1 opinión"
155msgstr[1] "%1 opinións"
155msgstr[1] "%1 opinións"
156
156
157−#: Dash/Apps/AppPreview.qml:126
157+#: Dash/Apps/AppPreview.qml:135
158msgid "Rate this"
158msgid "Rate this"
159msgstr "Valore isto"
159msgstr "Valore isto"
160
160
@@ -174,7 +174,7 @@ msgstr "Enviar"
174msgid "Comments:"
174msgid "Comments:"
175msgstr "Comentarios:"
175msgstr "Comentarios:"
176
176
177−#: Greeter/Lockscreen.qml:142
177+#: Greeter/Lockscreen.qml:146
178msgid "Emergency Call"
178msgid "Emergency Call"
179msgstr "Chamada de emerxencia"
179msgstr "Chamada de emerxencia"
180
180
@@ -207,11 +207,24 @@ msgstr "Fale agora…"
207msgid "Speaking..."
207msgid "Speaking..."
208msgstr "Falando…"
208msgstr "Falando…"
209
209
210+#: Notifications/NotificationMenuItemFactory.qml:89
211+msgid "Show password"
212+msgstr ""
213+
210#: Panel/SearchIndicator.qml:27
214#: Panel/SearchIndicator.qml:27
211msgid "Search"
215msgid "Search"
212msgstr "Buscar"
216msgstr "Buscar"
213
217
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
215msgid "Sorry, there is nothing that matches your search."
228msgid "Sorry, there is nothing that matches your search."
216msgstr "Sentímolo, non hai nada que coincida con esta busca."
229msgstr "Sentímolo, non hai nada que coincida con esta busca."
217
230
@@ -219,25 +232,7 @@ msgstr "Sentímolo, non hai nada que coincida con esta busca."
219msgid "All"
232msgid "All"
220msgstr "Todo"
233msgstr "Todo"
221
234
222−#: Shell.qml:438
235+#: Shell.qml:441
223#, qt-format
236#, qt-format
224msgid "Please enter %1"
237msgid "Please enter %1"
225msgstr "Introduza %1"
238msgstr "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+26−32
@@ -7,16 +7,16 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11−"PO-Revision-Date: 2013-10-01 09:19+0000\n"
11+"PO-Revision-Date: 2013-11-20 08:30+0000\n"
12"Last-Translator: Yaron <sh.yaron@gmail.com>\n"
12"Last-Translator: Yaron <sh.yaron@gmail.com>\n"
13"Language-Team: Hebrew <he@li.org>\n"
13"Language-Team: Hebrew <he@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-21 06:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "ויקיפדיה"
86msgid "YouTube"
86msgid "YouTube"
87msgstr "YouTube"
87msgstr "YouTube"
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr "לדלג על הפתיחה"
91msgstr "לדלג על הפתיחה"
92
92
@@ -131,8 +131,10 @@ msgid ""
131"You have now mastered the edge gestures and can start using the "
131"You have now mastered the edge gestures and can start using the "
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134+"עתה מכשסיימת את ההשתלמות לשימוש במחוות קצה יש לך את הכלים להשתמש "
135+"בטלפון<br><br>ניתן לגעת במקום כלשהו במסך כדי להתחיל"
134
136
135−#: Components/PageHeader.qml:341
137+#: Components/PageHeader.qml:345
136msgid "Recent searches"
138msgid "Recent searches"
137msgstr "חיפושים אחרונים"
139msgstr "חיפושים אחרונים"
138
140
@@ -152,7 +154,7 @@ msgid_plural "%1 reviews"
152msgstr[0] "סקירה %1"
154msgstr[0] "סקירה %1"
153msgstr[1] "%1 סקירות"
155msgstr[1] "%1 סקירות"
154
156
155−#: Dash/Apps/AppPreview.qml:126
157+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
158msgid "Rate this"
157msgstr "דירוג היישום"
159msgstr "דירוג היישום"
158
160
@@ -172,7 +174,7 @@ msgstr "שליחה"
172msgid "Comments:"
174msgid "Comments:"
173msgstr "הערות:"
175msgstr "הערות:"
174
176
175−#: Greeter/Lockscreen.qml:142
177+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
178msgid "Emergency Call"
177msgstr "שיחת חירום"
179msgstr "שיחת חירום"
178
180
@@ -205,40 +207,32 @@ msgstr "יש לדבר כעת..."
205msgid "Speaking..."
207msgid "Speaking..."
206msgstr "הדיבור מושמע…"
208msgstr "הדיבור מושמע…"
207
209
210+#: Notifications/NotificationMenuItemFactory.qml:89
211+msgid "Show password"
212+msgstr "הצגת הססמה"
213+
208#: Panel/SearchIndicator.qml:27
214#: Panel/SearchIndicator.qml:27
209msgid "Search"
215msgid "Search"
210msgstr "חיפוש"
216msgstr "חיפוש"
211
217
212−#: 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
213msgid "Sorry, there is nothing that matches your search."
228msgid "Sorry, there is nothing that matches your search."
214msgstr "שום דבר אינו תואם לחיפוש שלך, עמך הסליחה."
229msgstr "שום דבר אינו תואם לחיפוש שלך, עמך הסליחה."
215
230
216#: plugins/Unity/showallfilteroption.cpp:41
231#: plugins/Unity/showallfilteroption.cpp:41
217msgid "All"
232msgid "All"
218−msgstr ""
233+msgstr "הכול"
219
234
220−#: Shell.qml:438
235+#: Shell.qml:441
221#, qt-format
236#, qt-format
222msgid "Please enter %1"
237msgid "Please enter %1"
223msgstr "נא להזין %1"
238msgstr "נא להזין %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 ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-06-27 04:14+0000\n"
11"PO-Revision-Date: 2013-06-27 04:14+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Croatian <hr@li.org>\n"
13"Language-Team: Croatian <hr@li.org>\n"
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
17"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
18"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
18"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
20−"X-Generator: Launchpad (build 16799)\n"
20+"X-Generator: Launchpad (build 16831)\n"
21
21
22#: Applications/applications.js:23
22#: Applications/applications.js:23
23msgid "Phone"
23msgid "Phone"
@@ -87,7 +87,7 @@ msgstr ""
87msgid "YouTube"
87msgid "YouTube"
88msgstr ""
88msgstr ""
89
89
90−#: Components/EdgeDemoOverlay.qml:149
90+#: Components/EdgeDemoOverlay.qml:151
91msgid "Skip intro"
91msgid "Skip intro"
92msgstr ""
92msgstr ""
93
93
@@ -133,7 +133,7 @@ msgid ""
133"phone<br><br>Tap anywhere to start"
133"phone<br><br>Tap anywhere to start"
134msgstr ""
134msgstr ""
135
135
136−#: Components/PageHeader.qml:341
136+#: Components/PageHeader.qml:345
137msgid "Recent searches"
137msgid "Recent searches"
138msgstr "Nedavne pretrage"
138msgstr "Nedavne pretrage"
139
139
@@ -153,7 +153,7 @@ msgid_plural "%1 reviews"
153msgstr[0] ""
153msgstr[0] ""
154msgstr[1] ""
154msgstr[1] ""
155
155
156−#: Dash/Apps/AppPreview.qml:126
156+#: Dash/Apps/AppPreview.qml:135
157msgid "Rate this"
157msgid "Rate this"
158msgstr ""
158msgstr ""
159
159
@@ -173,7 +173,7 @@ msgstr ""
173msgid "Comments:"
173msgid "Comments:"
174msgstr ""
174msgstr ""
175
175
176−#: Greeter/Lockscreen.qml:142
176+#: Greeter/Lockscreen.qml:146
177msgid "Emergency Call"
177msgid "Emergency Call"
178msgstr ""
178msgstr ""
179
179
@@ -206,11 +206,24 @@ msgstr "Recite..."
206msgid "Speaking..."
206msgid "Speaking..."
207msgstr "Govor..."
207msgstr "Govor..."
208
208
209+#: Notifications/NotificationMenuItemFactory.qml:89
210+msgid "Show password"
211+msgstr ""
212+
209#: Panel/SearchIndicator.qml:27
213#: Panel/SearchIndicator.qml:27
210msgid "Search"
214msgid "Search"
211msgstr "Pretraživanje"
215msgstr "Pretraživanje"
212
216
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
214msgid "Sorry, there is nothing that matches your search."
227msgid "Sorry, there is nothing that matches your search."
215msgstr "Nažalost, ne postoji ništa što odgovara vašoj pretrazi."
228msgstr "Nažalost, ne postoji ništa što odgovara vašoj pretrazi."
216
229
@@ -218,13 +231,7 @@ msgstr "Nažalost, ne postoji ništa što odgovara vašoj pretrazi."
218msgid "All"
231msgid "All"
219msgstr ""
232msgstr ""
220
233
221−#: Shell.qml:438
234+#: Shell.qml:441
222#, qt-format
235#, qt-format
223msgid "Please enter %1"
236msgid "Please enter %1"
224msgstr ""
237msgstr ""
225−
226−#~ msgid "Music"
227−#~ msgstr "Glazba"
228−
229−#~ msgid "Videos"
230−#~ msgstr "Video"
po/hu.po+22−15
@@ -7,7 +7,7 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-06-27 04:28+0000\n"
11"PO-Revision-Date: 2013-06-27 04:28+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Hungarian <hu@li.org>\n"
13"Language-Team: Hungarian <hu@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
86msgid "YouTube"
86msgid "YouTube"
87msgstr ""
87msgstr ""
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr "Legutóbbi keresések"
137msgstr "Legutóbbi keresések"
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr ""
172msgid "Comments:"
172msgid "Comments:"
173msgstr ""
173msgstr ""
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr "Beszéljen most…"
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr "Beszéd…"
206msgstr "Beszéd…"
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr "Keresés"
214msgstr "Keresés"
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr "Elnézést, nincs találat a keresésre."
227msgstr "Elnézést, nincs találat a keresésre."
215
228
@@ -217,13 +230,7 @@ msgstr "Elnézést, nincs találat a keresésre."
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr ""
236msgstr ""
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 ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-06-27 04:43+0000\n"
11"PO-Revision-Date: 2013-06-27 04:43+0000\n"
12"Last-Translator: iAbaS <sosabazyan@yandex.ru>\n"
12"Last-Translator: iAbaS <sosabazyan@yandex.ru>\n"
13"Language-Team: Armenian <hy@li.org>\n"
13"Language-Team: Armenian <hy@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
86msgid "YouTube"
86msgid "YouTube"
87msgstr ""
87msgstr ""
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr "Վերջին որոնումներ"
137msgstr "Վերջին որոնումներ"
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr ""
172msgid "Comments:"
172msgid "Comments:"
173msgstr ""
173msgstr ""
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr "Խոսի՛ր"
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr "Խոսում եմ..."
206msgstr "Խոսում եմ..."
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr "Որոնում"
214msgstr "Որոնում"
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr "Կներերք, բայց Ձեր հարցումով ոչինչ չկար"
227msgstr "Կներերք, բայց Ձեր հարցումով ոչինչ չկար"
215
228
@@ -217,13 +230,7 @@ msgstr "Կներերք, բայց Ձեր հարցումով ոչինչ չկար"
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr ""
236msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Երգեր"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Վիդեոներ"
po/id.po+22−9
@@ -7,7 +7,7 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-06-26 22:35+0000\n"
11"PO-Revision-Date: 2013-06-26 22:35+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Indonesian <id@li.org>\n"
13"Language-Team: Indonesian <id@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
86msgid "YouTube"
86msgid "YouTube"
87msgstr ""
87msgstr ""
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr ""
137msgstr ""
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr ""
172msgid "Comments:"
172msgid "Comments:"
173msgstr ""
173msgstr ""
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr ""
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr ""
206msgstr ""
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr ""
214msgstr ""
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr ""
227msgstr ""
215
228
@@ -217,7 +230,7 @@ msgstr ""
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr ""
236msgstr ""
po/is.po+22−30
@@ -7,7 +7,7 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity8\n"
8"Project-Id-Version: unity8\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-09-18 16:22+0000\n"
11"PO-Revision-Date: 2013-09-18 16:22+0000\n"
12"Last-Translator: Andri Thorlacius <Unknown>\n"
12"Last-Translator: Andri Thorlacius <Unknown>\n"
13"Language-Team: Icelandic <is@li.org>\n"
13"Language-Team: Icelandic <is@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Wikipedia"
86msgid "YouTube"
86msgid "YouTube"
87msgstr "YouTube"
87msgstr "YouTube"
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr "Hoppa yfir kynningu"
91msgstr "Hoppa yfir kynningu"
92
92
@@ -133,7 +133,7 @@ msgid ""
133"phone<br><br>Tap anywhere to start"
133"phone<br><br>Tap anywhere to start"
134msgstr ""
134msgstr ""
135
135
136−#: Components/PageHeader.qml:341
136+#: Components/PageHeader.qml:345
137msgid "Recent searches"
137msgid "Recent searches"
138msgstr "Nýlegar leitir"
138msgstr "Nýlegar leitir"
139
139
@@ -153,7 +153,7 @@ msgid_plural "%1 reviews"
153msgstr[0] "%1 ummæli"
153msgstr[0] "%1 ummæli"
154msgstr[1] "%1 ummæli"
154msgstr[1] "%1 ummæli"
155
155
156−#: Dash/Apps/AppPreview.qml:126
156+#: Dash/Apps/AppPreview.qml:135
157msgid "Rate this"
157msgid "Rate this"
158msgstr "Gefa þessu einkunn"
158msgstr "Gefa þessu einkunn"
159
159
@@ -173,7 +173,7 @@ msgstr "Senda"
173msgid "Comments:"
173msgid "Comments:"
174msgstr "Athugasemdir:"
174msgstr "Athugasemdir:"
175
175
176−#: Greeter/Lockscreen.qml:142
176+#: Greeter/Lockscreen.qml:146
177msgid "Emergency Call"
177msgid "Emergency Call"
178msgstr "Neyðarsímtal"
178msgstr "Neyðarsímtal"
179
179
@@ -206,11 +206,24 @@ msgstr "Talaðu Núna..."
206msgid "Speaking..."
206msgid "Speaking..."
207msgstr "Tala..."
207msgstr "Tala..."
208
208
209+#: Notifications/NotificationMenuItemFactory.qml:89
210+msgid "Show password"
211+msgstr ""
212+
209#: Panel/SearchIndicator.qml:27
213#: Panel/SearchIndicator.qml:27
210msgid "Search"
214msgid "Search"
211msgstr "Leita"
215msgstr "Leita"
212
216
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
214msgid "Sorry, there is nothing that matches your search."
227msgid "Sorry, there is nothing that matches your search."
215msgstr "Því miður, það var ekkert sem passaði við leitarorðið þitt."
228msgstr "Því miður, það var ekkert sem passaði við leitarorðið þitt."
216
229
@@ -218,28 +231,7 @@ msgstr "Því miður, það var ekkert sem passaði við leitarorðið þitt."
218msgid "All"
231msgid "All"
219msgstr ""
232msgstr ""
220
233
221−#: Shell.qml:438
234+#: Shell.qml:441
222#, qt-format
235#, qt-format
223msgid "Please enter %1"
236msgid "Please enter %1"
224msgstr ""
237msgstr ""
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 ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-10-07 09:34+0000\n"
11"PO-Revision-Date: 2013-10-07 09:34+0000\n"
12"Last-Translator: Claudio Arseni <claudio.arseni@gmail.com>\n"
12"Last-Translator: Claudio Arseni <claudio.arseni@gmail.com>\n"
13"Language-Team: Italian <it@li.org>\n"
13"Language-Team: Italian <it@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Wikipedia"
86msgid "YouTube"
86msgid "YouTube"
87msgstr "YouTube"
87msgstr "YouTube"
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr "Salta introduzione"
91msgstr "Salta introduzione"
92
92
@@ -139,7 +139,7 @@ msgstr ""
139"I gesti sui bordi sono stati configurati ed è possibile iniziare a usare il "
139"I gesti sui bordi sono stati configurati ed è possibile iniziare a usare il "
140"telefono<br><br>Toccare in un punto qualunque per iniziare"
140"telefono<br><br>Toccare in un punto qualunque per iniziare"
141
141
142−#: Components/PageHeader.qml:341
142+#: Components/PageHeader.qml:345
143msgid "Recent searches"
143msgid "Recent searches"
144msgstr "Ricerche recenti"
144msgstr "Ricerche recenti"
145
145
@@ -159,7 +159,7 @@ msgid_plural "%1 reviews"
159msgstr[0] "%1 recensione"
159msgstr[0] "%1 recensione"
160msgstr[1] "%1 recensioni"
160msgstr[1] "%1 recensioni"
161
161
162−#: Dash/Apps/AppPreview.qml:126
162+#: Dash/Apps/AppPreview.qml:135
163msgid "Rate this"
163msgid "Rate this"
164msgstr "Valuta"
164msgstr "Valuta"
165
165
@@ -179,7 +179,7 @@ msgstr "Invia"
179msgid "Comments:"
179msgid "Comments:"
180msgstr "Commenti:"
180msgstr "Commenti:"
181
181
182−#: Greeter/Lockscreen.qml:142
182+#: Greeter/Lockscreen.qml:146
183msgid "Emergency Call"
183msgid "Emergency Call"
184msgstr "Chiamata di emergenza"
184msgstr "Chiamata di emergenza"
185
185
@@ -212,11 +212,24 @@ msgstr "Parla ora..."
212msgid "Speaking..."
212msgid "Speaking..."
213msgstr "Sto parlando..."
213msgstr "Sto parlando..."
214
214
215+#: Notifications/NotificationMenuItemFactory.qml:89
216+msgid "Show password"
217+msgstr ""
218+
215#: Panel/SearchIndicator.qml:27
219#: Panel/SearchIndicator.qml:27
216msgid "Search"
220msgid "Search"
217msgstr "Cerca"
221msgstr "Cerca"
218
222
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
220msgid "Sorry, there is nothing that matches your search."
233msgid "Sorry, there is nothing that matches your search."
221msgstr "Nessun risultato corrispondente alla ricerca."
234msgstr "Nessun risultato corrispondente alla ricerca."
222
235
@@ -224,28 +237,7 @@ msgstr "Nessun risultato corrispondente alla ricerca."
224msgid "All"
237msgid "All"
225msgstr "Tutto"
238msgstr "Tutto"
226
239
227−#: Shell.qml:438
240+#: Shell.qml:441
228#, qt-format
241#, qt-format
229msgid "Please enter %1"
242msgid "Please enter %1"
230msgstr "Inserire %1"
243msgstr "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 ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-06-26 22:36+0000\n"
11"PO-Revision-Date: 2013-06-26 22:36+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Japanese <ja@li.org>\n"
13"Language-Team: Japanese <ja@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
86msgid "YouTube"
86msgid "YouTube"
87msgstr ""
87msgstr ""
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr ""
137msgstr ""
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr ""
172msgid "Comments:"
172msgid "Comments:"
173msgstr ""
173msgstr ""
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr ""
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr ""
206msgstr ""
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr ""
214msgstr ""
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr ""
227msgstr ""
215
228
@@ -217,7 +230,7 @@ msgstr ""
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr ""
236msgstr ""
po/km.po+23−31
@@ -7,16 +7,16 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity8\n"
8"Project-Id-Version: unity8\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11−"PO-Revision-Date: 2013-10-11 08:49+0000\n"
11+"PO-Revision-Date: 2013-11-20 07:34+0000\n"
12"Last-Translator: Khoem Sokhem <khoemsokhem@khmeros.info>\n"
12"Last-Translator: Khoem Sokhem <khoemsokhem@khmeros.info>\n"
13"Language-Team: Khmer <km@li.org>\n"
13"Language-Team: Khmer <km@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-21 06:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "វីគីភីឌៀ"
86msgid "YouTube"
86msgid "YouTube"
87msgstr "YouTube"
87msgstr "YouTube"
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr "រំលង​ការ​ណែនាំ"
91msgstr "រំលង​ការ​ណែនាំ"
92
92
@@ -137,7 +137,7 @@ msgstr ""
137"និង​អាច​ចាប់ផ្ដើម​ប្រើ​ទូរស័ព្ទ​បាន<br><br>ប៉ះ​កន្លែង​ណា​មួយ​ "
137"និង​អាច​ចាប់ផ្ដើម​ប្រើ​ទូរស័ព្ទ​បាន<br><br>ប៉ះ​កន្លែង​ណា​មួយ​ "
138"ដើម្បី​ចាប់ផ្ដើម"
138"ដើម្បី​ចាប់ផ្ដើម"
139
139
140−#: Components/PageHeader.qml:341
140+#: Components/PageHeader.qml:345
141msgid "Recent searches"
141msgid "Recent searches"
142msgstr "ការ​ស្វែងរក​ថ្មី"
142msgstr "ការ​ស្វែងរក​ថ្មី"
143
143
@@ -156,7 +156,7 @@ msgid "%1 review"
156msgid_plural "%1 reviews"
156msgid_plural "%1 reviews"
157msgstr[0] "ពិនិត្យ​មើល %1"
157msgstr[0] "ពិនិត្យ​មើល %1"
158
158
159−#: Dash/Apps/AppPreview.qml:126
159+#: Dash/Apps/AppPreview.qml:135
160msgid "Rate this"
160msgid "Rate this"
161msgstr "វាយតម្លៃ​វា"
161msgstr "វាយតម្លៃ​វា"
162
162
@@ -176,7 +176,7 @@ msgstr "ផ្ញើ"
176msgid "Comments:"
176msgid "Comments:"
177msgstr "មតិយោបល់៖"
177msgstr "មតិយោបល់៖"
178
178
179−#: Greeter/Lockscreen.qml:142
179+#: Greeter/Lockscreen.qml:146
180msgid "Emergency Call"
180msgid "Emergency Call"
181msgstr "ការ​ហៅ​ពេល​អាសន្ន"
181msgstr "ការ​ហៅ​ពេល​អាសន្ន"
182
182
@@ -209,11 +209,24 @@ msgstr "និយាយ​ឥឡូវ..."
209msgid "Speaking..."
209msgid "Speaking..."
210msgstr "កំពុង​និយាយ..."
210msgstr "កំពុង​និយាយ..."
211
211
212+#: Notifications/NotificationMenuItemFactory.qml:89
213+msgid "Show password"
214+msgstr "បង្ហាញ​ពាក្យ​សម្ងាត់"
215+
212#: Panel/SearchIndicator.qml:27
216#: Panel/SearchIndicator.qml:27
213msgid "Search"
217msgid "Search"
214msgstr "ស្វែង​រក"
218msgstr "ស្វែង​រក"
215
219
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
217msgid "Sorry, there is nothing that matches your search."
230msgid "Sorry, there is nothing that matches your search."
218msgstr "សូម​ទោស មិនមាន​ពាក្យ​ដែល​អ្នក​ស្វែងរក​ទេ​។"
231msgstr "សូម​ទោស មិនមាន​ពាក្យ​ដែល​អ្នក​ស្វែងរក​ទេ​។"
219
232
@@ -221,28 +234,7 @@ msgstr "សូម​ទោស មិនមាន​ពាក្យ​ដែល
221msgid "All"
234msgid "All"
222msgstr "ទាំង​អស់"
235msgstr "ទាំង​អស់"
223
236
224−#: Shell.qml:438
237+#: Shell.qml:441
225#, qt-format
238#, qt-format
226msgid "Please enter %1"
239msgid "Please enter %1"
227msgstr "សូម​បញ្ចូល %1"
240msgstr "សូម​បញ្ចូល %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 ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-06-27 05:43+0000\n"
11"PO-Revision-Date: 2013-06-27 05:43+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Kannada <kn@li.org>\n"
13"Language-Team: Kannada <kn@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
86msgid "YouTube"
86msgid "YouTube"
87msgstr ""
87msgstr ""
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr "ಇತ್ತೀಚಿನ ಹುಡುಕಾಟಗಳು"
137msgstr "ಇತ್ತೀಚಿನ ಹುಡುಕಾಟಗಳು"
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr ""
172msgid "Comments:"
172msgid "Comments:"
173msgstr ""
173msgstr ""
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr "ಈಗ ಮಾತನಾಡಿ ..."
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr "ಮಾತನಾಡುತಿದ್ದೀರಿ"
206msgstr "ಮಾತನಾಡುತಿದ್ದೀರಿ"
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr "ಹುಡುಕು"
214msgstr "ಹುಡುಕು"
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr "ಕ್ಷಮಿಸಿ ನಿಮ್ಮ ಶೋಧನೆಗೆ ಸರಿಯಾದ ಹೊಂದಾಣಿಕೆಗಳು ದೊರಕುತ್ತಿಲ್ಲ"
227msgstr "ಕ್ಷಮಿಸಿ ನಿಮ್ಮ ಶೋಧನೆಗೆ ಸರಿಯಾದ ಹೊಂದಾಣಿಕೆಗಳು ದೊರಕುತ್ತಿಲ್ಲ"
215
228
@@ -217,13 +230,7 @@ msgstr "ಕ್ಷಮಿಸಿ ನಿಮ್ಮ ಶೋಧನೆಗೆ ಸರಿಯ
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr ""
236msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "ಸಂಗೀತ"
227−
228−#~ msgid "Videos"
229−#~ msgstr "ವೀಡಿಯೋಗಳು"
po/ko.po+22−12
@@ -7,7 +7,7 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-10-10 07:04+0000\n"
11"PO-Revision-Date: 2013-10-10 07:04+0000\n"
12"Last-Translator: Kim Boram <boramism@gmail.com>\n"
12"Last-Translator: Kim Boram <boramism@gmail.com>\n"
13"Language-Team: Korean <ko@li.org>\n"
13"Language-Team: Korean <ko@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "위키백과"
86msgid "YouTube"
86msgid "YouTube"
87msgstr "유튜브"
87msgstr "유튜브"
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr "도입부 건너뛰기"
91msgstr "도입부 건너뛰기"
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr "최근 검색"
137msgstr "최근 검색"
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr ""
172msgid "Comments:"
172msgid "Comments:"
173msgstr ""
173msgstr ""
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr ""
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr ""
206msgstr ""
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr "검색"
214msgstr "검색"
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr ""
227msgstr ""
215
228
@@ -217,10 +230,7 @@ msgstr ""
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr ""
236msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "음악"
po/ky.po+22−15
@@ -7,7 +7,7 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-06-27 06:17+0000\n"
11"PO-Revision-Date: 2013-06-27 06:17+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Kirghiz <ky@li.org>\n"
13"Language-Team: Kirghiz <ky@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
86msgid "YouTube"
86msgid "YouTube"
87msgstr ""
87msgstr ""
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr "Соңку издөөлөр"
137msgstr "Соңку издөөлөр"
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr ""
172msgid "Comments:"
172msgid "Comments:"
173msgstr ""
173msgstr ""
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr "Азыр сүйлөңүз..."
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr "Сүйлөнүүдө..."
206msgstr "Сүйлөнүүдө..."
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr "Издөө"
214msgstr "Издөө"
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr "Тилекке каршы, сиздин издөөңүзгө эч нерсе дал келген жок."
227msgstr "Тилекке каршы, сиздин издөөңүзгө эч нерсе дал келген жок."
215
228
@@ -217,13 +230,7 @@ msgstr "Тилекке каршы, сиздин издөөңүзгө эч нер
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr ""
236msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Музыка"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Видеолор"
po/lo.po+22−15
@@ -7,7 +7,7 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity8\n"
8"Project-Id-Version: unity8\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-10-02 10:00+0000\n"
11"PO-Revision-Date: 2013-10-02 10:00+0000\n"
12"Last-Translator: Anousak <anousak@gmail.com>\n"
12"Last-Translator: Anousak <anousak@gmail.com>\n"
13"Language-Team: Lao <lo@li.org>\n"
13"Language-Team: Lao <lo@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
86msgid "YouTube"
86msgid "YouTube"
87msgstr "ິYouTube"
87msgstr "ິYouTube"
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr ""
137msgstr ""
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr "ສົ່ງ"
172msgid "Comments:"
172msgid "Comments:"
173msgstr "ຄໍ່ເຫັນ"
173msgstr "ຄໍ່ເຫັນ"
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr "ເວົ້າໂລດ"
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr "ກໍາລັງເວົ້າ"
206msgstr "ກໍາລັງເວົ້າ"
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr "ຊອກຫາ"
214msgstr "ຊອກຫາ"
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr ""
227msgstr ""
215
228
@@ -217,13 +230,7 @@ msgstr ""
217msgid "All"
230msgid "All"
218msgstr "ທັງໝົດ"
231msgstr "ທັງໝົດ"
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr "ກະລູນາປ້ອນ %1"
236msgstr "ກະລູນາປ້ອນ %1"
224−
225−#~ msgid "Videos"
226−#~ msgstr "ວິດີໂອ"
227−
228−#~ msgid "Music"
229−#~ msgstr "ດົນຕີ"
po/lv.po+22−15
@@ -7,7 +7,7 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-09-28 16:29+0000\n"
11"PO-Revision-Date: 2013-09-28 16:29+0000\n"
12"Last-Translator: Jānis-Marks Gailis <jeanmarc.gailis@gmail.com>\n"
12"Last-Translator: Jānis-Marks Gailis <jeanmarc.gailis@gmail.com>\n"
13"Language-Team: Latvian <lv@li.org>\n"
13"Language-Team: Latvian <lv@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2;\n"
17"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"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Vikipēdija"
86msgid "YouTube"
86msgid "YouTube"
87msgstr "YouTube"
87msgstr "YouTube"
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr "Nesen veiktās meklēšanas"
137msgstr "Nesen veiktās meklēšanas"
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr ""
172msgid "Comments:"
172msgid "Comments:"
173msgstr ""
173msgstr ""
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr "Runajiet Tagad"
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr "Runa..."
206msgstr "Runa..."
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr "Meklēt"
214msgstr "Meklēt"
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr "Diemžēl nekas neatbilst jūsu meklētajam."
227msgstr "Diemžēl nekas neatbilst jūsu meklētajam."
215
228
@@ -217,13 +230,7 @@ msgstr "Diemžēl nekas neatbilst jūsu meklētajam."
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr ""
236msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Mūzika"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Video"
po/ml.ponew file+240
@@ -0,0 +1,240 @@
1+# Malayalam translation for unity8
2+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
3+# This file is distributed under the same license as the unity8 package.
4+# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
5+#
6+msgid ""
7+msgstr ""
8+"Project-Id-Version: unity8\n"
9+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11+"PO-Revision-Date: 2013-11-23 11:44+0000\n"
12+"Last-Translator: STyM Alfazz <Unknown>\n"
13+"Language-Team: Malayalam <ml@li.org>\n"
14+"MIME-Version: 1.0\n"
15+"Content-Type: text/plain; charset=UTF-8\n"
16+"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
18+"X-Launchpad-Export-Date: 2013-11-24 05:50+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
20+
21+#: Applications/applications.js:23
22+msgid "Phone"
23+msgstr "ഫോണ്‍"
24+
25+#: Applications/applications.js:29
26+msgid "Camera"
27+msgstr "ക്യാമറ"
28+
29+#: Applications/applications.js:35
30+msgid "Gallery"
31+msgstr "ഗ്യാലറി"
32+
33+#: Applications/applications.js:40
34+msgid "Facebook"
35+msgstr "ഫേസ്ബുക്ക്"
36+
37+#: Applications/applications.js:46
38+msgid "Browser"
39+msgstr "ബ്രൗസര്‍"
40+
41+#: Applications/applications.js:51
42+msgid "Twitter"
43+msgstr "ട്വിറ്റര്‍"
44+
45+#: Applications/applications.js:57
46+msgid "GMail"
47+msgstr "ജിമെയില്‍"
48+
49+#: Applications/applications.js:62
50+msgid "Weather"
51+msgstr "കാലാവസ്ഥ"
52+
53+#: Applications/applications.js:68
54+msgid "Notepad"
55+msgstr "നോട്പാഡ്"
56+
57+#: Applications/applications.js:74
58+msgid "Calendar"
59+msgstr "കലണ്ടര്‍"
60+
61+#: Applications/applications.js:80
62+msgid "Media Player"
63+msgstr "മീഡിയ പ്ലെയര്‍"
64+
65+#: Applications/applications.js:86
66+msgid "Evernote"
67+msgstr "എവര്‍നോട്ട്"
68+
69+#: Applications/applications.js:91
70+msgid "Map"
71+msgstr "ഭുപടം"
72+
73+#: Applications/applications.js:96
74+msgid "Pinterest"
75+msgstr "പിന്‍ട്രസ്റ്റ്"
76+
77+#: Applications/applications.js:101
78+msgid "SoundCloud"
79+msgstr "സൗണ്ട്ക്ലൗഡ്"
80+
81+#: Applications/applications.js:106
82+msgid "Wikipedia"
83+msgstr "വിക്കിപീഡിയ"
84+
85+#: Applications/applications.js:111
86+msgid "YouTube"
87+msgstr "യുട്യൂബ്"
88+
89+#: Components/EdgeDemoOverlay.qml:151
90+msgid "Skip intro"
91+msgstr "ആമുഖം ഒഴിവാക്കുക"
92+
93+#: Components/EdgeDemo.qml:112
94+msgid "Right edge"
95+msgstr "വലത് മൂല"
96+
97+#: Components/EdgeDemo.qml:113
98+msgid "Try swiping from the right edge to unlock the phone"
99+msgstr "ഫോണ്‍ അണ്‍ലോക്ക് ചെയ്യാന്‍ വലതു വശത്തുനിന്ന് സ്വൈപ് ചെയ്ത് നോക്കുക"
100+
101+#: Components/EdgeDemo.qml:144
102+msgid "Top edge"
103+msgstr "മുകള്‍ വശം"
104+
105+#: Components/EdgeDemo.qml:145
106+msgid "Try swiping from the top edge to access the indicators"
107+msgstr "സൂചകങ്ങള്‍ ലഭ്യമാക്കാന്‍ മുകള്‍ വശത്തുനിന്നും സ്വൈപ് ചെയ്യുക"
108+
109+#: Components/EdgeDemo.qml:170
110+msgid "Close"
111+msgstr "അടക്കുക"
112+
113+#: Components/EdgeDemo.qml:171
114+msgid "Swipe up again to close the settings screen"
115+msgstr "ക്രമീകരണങ്ങളുടെ സ്ക്രീന്‍ അടക്കാന്‍ മുകളിലേക്ക് സ്വൈപ് ചെയ്യുക"
116+
117+#: Components/EdgeDemo.qml:198
118+msgid "Left edge"
119+msgstr "ഇടത് വശം"
120+
121+#: Components/EdgeDemo.qml:199
122+msgid "Swipe from the left to reveal the launcher for quick access to apps"
123+msgstr ""
124+"പ്രയോഗങ്ങള്‍ പെട്ടെന്ന് ലഭ്യമാക്കുന്ന വിക്ഷേപിക ലഭ്യമാക്കാന്‍ ഇടതു വശത്ത് "
125+"നിന്നും സ്വൈപ് ചെയ്യുക"
126+
127+#: Components/EdgeDemo.qml:226
128+msgid "Well done"
129+msgstr "നന്നായി ചെയ്തിരിക്കുന്നു"
130+
131+#: Components/EdgeDemo.qml:227
132+msgid ""
133+"You have now mastered the edge gestures and can start using the "
134+"phone<br><br>Tap anywhere to start"
135+msgstr ""
136+"നിങ്ങളിപ്പോള്‍ സ്വൈപുകളും മറ്റും പഠിച്ചിരിക്കുന്നു<br><br>തുടങ്ങാന്‍ "
137+"എവിടെയെങ്കിലും ടാപ് ചെയ്യുക"
138+
139+#: Components/PageHeader.qml:345
140+msgid "Recent searches"
141+msgstr "സമീപകാല തിരയലുകള്‍"
142+
143+#. TRANSLATORS: Number of persons who rated this app
144+#. TRANSLATORS: Number of persons who rated this app/video/whatever
145+#: Dash/Apps/AppInfo.qml:73 Dash/Previews/Header.qml:93
146+#, qt-format
147+msgid "(%1)"
148+msgstr "(%1)"
149+
150+#. TRANSLATORS: Number of persons who wrote reviews for this app
151+#. TRANSLATORS: Number of persons who wrote reviews for this app/video/whatever
152+#: Dash/Apps/AppInfo.qml:85 Dash/Previews/Header.qml:105
153+#, qt-format
154+msgid "%1 review"
155+msgid_plural "%1 reviews"
156+msgstr[0] "%1 അവലോകനം"
157+msgstr[1] "%1 അവലോകനങ്ങള്‍"
158+
159+#: Dash/Apps/AppPreview.qml:135
160+msgid "Rate this"
161+msgstr "ഇത് അവലോകനം ചെയ്യുക"
162+
163+#: Dash/Previews/Reviews.qml:74
164+msgid "Add a review"
165+msgstr "ഒരു അവലോകനം ചേര്‍ക്കുക"
166+
167+#: Dash/Previews/Reviews.qml:86
168+msgid "Review"
169+msgstr "അവലോകനം"
170+
171+#: Dash/Previews/Reviews.qml:121
172+msgid "Send"
173+msgstr "അയയ്‌ക്കുക"
174+
175+#: Dash/Previews/Reviews.qml:139
176+msgid "Comments:"
177+msgstr "അഭിപ്രായങ്ങള്‍:"
178+
179+#: Greeter/Lockscreen.qml:146
180+msgid "Emergency Call"
181+msgstr "അടിയന്തിര വിളി"
182+
183+#: Greeter/PassphraseLockscreen.qml:59
184+#, qt-format
185+msgid "Hello %1"
186+msgstr "ഹലോ %1"
187+
188+#: Greeter/PassphraseLockscreen.qml:59
189+msgid "Hello"
190+msgstr "ഹലോ"
191+
192+#: Hud/HudParametrizedActionsPage.qml:132
193+msgid "Confirm"
194+msgstr "സ്ഥിരീകരിക്കുക"
195+
196+#: Hud/Hud.qml:61 Hud/Hud.qml:99 Hud/Hud.qml:372
197+msgid "Type or say a command"
198+msgstr "ഒരു ആജ്ഞ പറയുകയോ ടൈപ്പുകയോ ചെയ്യുക"
199+
200+#: Hud/Hud.qml:84
201+msgid "Loading. Please Wait..."
202+msgstr "വരുന്നു. ദയവായി കാത്തിരിക്കുക..."
203+
204+#: Hud/Hud.qml:89
205+msgid "Speak Now..."
206+msgstr "ഇപ്പോള്‍ സംസാരിക്കുക..."
207+
208+#: Hud/Hud.qml:94
209+msgid "Speaking..."
210+msgstr "സംസാരിക്കുന്നു..."
211+
212+#: Notifications/NotificationMenuItemFactory.qml:89
213+msgid "Show password"
214+msgstr "രഹസ്യവാക്ക് കാണിക്കുക"
215+
216+#: Panel/SearchIndicator.qml:27
217+msgid "Search"
218+msgstr "തിരയുക"
219+
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
230+msgid "Sorry, there is nothing that matches your search."
231+msgstr "ക്ഷമിക്കണം, താങ്കളുടെ തിരച്ചിലുമായി ഒത്തുപോകുന്ന ഒന്നും തന്നെയില്ല"
232+
233+#: plugins/Unity/showallfilteroption.cpp:41
234+msgid "All"
235+msgstr "എല്ലാം"
236+
237+#: Shell.qml:441
238+#, qt-format
239+msgid "Please enter %1"
240+msgstr "ദയവായി %1 നല്‍കുക"
po/my.po+22−24
@@ -7,7 +7,7 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-10-09 11:35+0000\n"
11"PO-Revision-Date: 2013-10-09 11:35+0000\n"
12"Last-Translator: Pyae Sone <Unknown>\n"
12"Last-Translator: Pyae Sone <Unknown>\n"
13"Language-Team: Burmese <my@li.org>\n"
13"Language-Team: Burmese <my@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "ဝီကီပီဒီးယား"
86msgid "YouTube"
86msgid "YouTube"
87msgstr "YouTube"
87msgstr "YouTube"
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr "မိတ်ဆက်ကိုကျော်မည်"
91msgstr "မိတ်ဆက်ကိုကျော်မည်"
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr "မကြာသေးခင်က ရှာဖွေခြင်း"
137msgstr "မကြာသေးခင်က ရှာဖွေခြင်း"
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr "ဒီဟာကိုအမှတ်ပေးမည်"
157msgstr "ဒီဟာကိုအမှတ်ပေးမည်"
158
158
@@ -172,7 +172,7 @@ msgstr "ပို့မည်"
172msgid "Comments:"
172msgid "Comments:"
173msgstr "မှတ်ချက်များ-"
173msgstr "မှတ်ချက်များ-"
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr "ယခုပြောပါ"
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr "ပြောနေသည်"
206msgstr "ပြောနေသည်"
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr "ရှာဖွေ"
214msgstr "ရှာဖွေ"
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr "ဆောရီး၊ သင်၏ရှာဖွေမူနှင့်တူညီတာဘာမှမရှိပါ။"
227msgstr "ဆောရီး၊ သင်၏ရှာဖွေမူနှင့်တူညီတာဘာမှမရှိပါ။"
215
228
@@ -217,22 +230,7 @@ msgstr "ဆောရီး၊ သင်၏ရှာဖွေမူနှင့
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr ""
236msgstr ""
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 ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-06-27 07:02+0000\n"
11"PO-Revision-Date: 2013-06-27 07:02+0000\n"
12"Last-Translator: Joakim Langvand <jlangvand@gmail.com>\n"
12"Last-Translator: Joakim Langvand <jlangvand@gmail.com>\n"
13"Language-Team: Norwegian Bokmal <nb@li.org>\n"
13"Language-Team: Norwegian Bokmal <nb@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
86msgid "YouTube"
86msgid "YouTube"
87msgstr ""
87msgstr ""
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr "Siste søk"
137msgstr "Siste søk"
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr ""
172msgid "Comments:"
172msgid "Comments:"
173msgstr ""
173msgstr ""
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr "Snakk nå …"
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr "Snakker …"
206msgstr "Snakker …"
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr "Søk"
214msgstr "Søk"
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr "Søket ga ingen treff."
227msgstr "Søket ga ingen treff."
215
228
@@ -217,13 +230,7 @@ msgstr "Søket ga ingen treff."
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr ""
236msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Musikk"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Videoer"
po/nl.po+22−15
@@ -7,7 +7,7 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-06-27 07:19+0000\n"
11"PO-Revision-Date: 2013-06-27 07:19+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Dutch <nl@li.org>\n"
13"Language-Team: Dutch <nl@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
86msgid "YouTube"
86msgid "YouTube"
87msgstr ""
87msgstr ""
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr "Recente zoekopdrachten"
137msgstr "Recente zoekopdrachten"
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr ""
172msgid "Comments:"
172msgid "Comments:"
173msgstr ""
173msgstr ""
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr "Nu inspreken…"
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr "Inspreken…"
206msgstr "Inspreken…"
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr "Zoeken"
214msgstr "Zoeken"
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr "Er is helaas niets dat met uw zoekopdracht overeenkomt."
227msgstr "Er is helaas niets dat met uw zoekopdracht overeenkomt."
215
228
@@ -217,13 +230,7 @@ msgstr "Er is helaas niets dat met uw zoekopdracht overeenkomt."
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr ""
236msgstr ""
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 ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-10-13 13:44+0000\n"
11"PO-Revision-Date: 2013-10-13 13:44+0000\n"
12"Last-Translator: GTriderXC <gtriderxc@yahoo.com>\n"
12"Last-Translator: GTriderXC <gtriderxc@yahoo.com>\n"
13"Language-Team: Polish <pl@li.org>\n"
13"Language-Team: Polish <pl@li.org>\n"
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
17"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
18"|| n%100>=20) ? 1 : 2;\n"
18"|| n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2013-10-14 05:47+0000\n"
19+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
20−"X-Generator: Launchpad (build 16799)\n"
20+"X-Generator: Launchpad (build 16831)\n"
21
21
22#: Applications/applications.js:23
22#: Applications/applications.js:23
23msgid "Phone"
23msgid "Phone"
@@ -87,7 +87,7 @@ msgstr "Wikipedia"
87msgid "YouTube"
87msgid "YouTube"
88msgstr "YouTube"
88msgstr "YouTube"
89
89
90−#: Components/EdgeDemoOverlay.qml:149
90+#: Components/EdgeDemoOverlay.qml:151
91msgid "Skip intro"
91msgid "Skip intro"
92msgstr "Pomiń intro"
92msgstr "Pomiń intro"
93
93
@@ -137,7 +137,7 @@ msgstr ""
137"Polecenia aktywatorów krawędzi ekranu zostały opanowane<br><br>Dotknij "
137"Polecenia aktywatorów krawędzi ekranu zostały opanowane<br><br>Dotknij "
138"gdziekolwiek aby kontynuować"
138"gdziekolwiek aby kontynuować"
139
139
140−#: Components/PageHeader.qml:341
140+#: Components/PageHeader.qml:345
141msgid "Recent searches"
141msgid "Recent searches"
142msgstr "Ostatnie wyszukiwania"
142msgstr "Ostatnie wyszukiwania"
143
143
@@ -158,7 +158,7 @@ msgstr[0] "%1 opinia"
158msgstr[1] "%1 opinie"
158msgstr[1] "%1 opinie"
159msgstr[2] "%1 opinii"
159msgstr[2] "%1 opinii"
160
160
161−#: Dash/Apps/AppPreview.qml:126
161+#: Dash/Apps/AppPreview.qml:135
162msgid "Rate this"
162msgid "Rate this"
163msgstr "Oceń to"
163msgstr "Oceń to"
164
164
@@ -178,7 +178,7 @@ msgstr "Wyślij"
178msgid "Comments:"
178msgid "Comments:"
179msgstr "Komentarze:"
179msgstr "Komentarze:"
180
180
181−#: Greeter/Lockscreen.qml:142
181+#: Greeter/Lockscreen.qml:146
182msgid "Emergency Call"
182msgid "Emergency Call"
183msgstr "Telefon ratunkowy"
183msgstr "Telefon ratunkowy"
184
184
@@ -211,11 +211,24 @@ msgstr "Mów teraz..."
211msgid "Speaking..."
211msgid "Speaking..."
212msgstr "Rozpoznanie..."
212msgstr "Rozpoznanie..."
213
213
214+#: Notifications/NotificationMenuItemFactory.qml:89
215+msgid "Show password"
216+msgstr ""
217+
214#: Panel/SearchIndicator.qml:27
218#: Panel/SearchIndicator.qml:27
215msgid "Search"
219msgid "Search"
216msgstr "Szukaj"
220msgstr "Szukaj"
217
221
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
219msgid "Sorry, there is nothing that matches your search."
232msgid "Sorry, there is nothing that matches your search."
220msgstr "Nie znaleziono pasujących wyników."
233msgstr "Nie znaleziono pasujących wyników."
221
234
@@ -223,7 +236,7 @@ msgstr "Nie znaleziono pasujących wyników."
223msgid "All"
236msgid "All"
224msgstr "Wszystko"
237msgstr "Wszystko"
225
238
226−#: Shell.qml:438
239+#: Shell.qml:441
227#, qt-format
240#, qt-format
228msgid "Please enter %1"
241msgid "Please enter %1"
229msgstr "Wprowadź %1"
242msgstr "Wprowadź %1"
po/pt_BR.po+22−30
@@ -7,7 +7,7 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-10-01 13:05+0000\n"
11"PO-Revision-Date: 2013-10-01 13:05+0000\n"
12"Last-Translator: Rafael Neri <Unknown>\n"
12"Last-Translator: Rafael Neri <Unknown>\n"
13"Language-Team: Brazilian Portuguese <pt_BR@li.org>\n"
13"Language-Team: Brazilian Portuguese <pt_BR@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n > 1;\n"
17"Plural-Forms: nplurals=2; plural=n > 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Wikipédia"
86msgid "YouTube"
86msgid "YouTube"
87msgstr "YouTube"
87msgstr "YouTube"
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr "Pular introdução"
91msgstr "Pular introdução"
92
92
@@ -134,7 +134,7 @@ msgid ""
134"phone<br><br>Tap anywhere to start"
134"phone<br><br>Tap anywhere to start"
135msgstr ""
135msgstr ""
136
136
137−#: Components/PageHeader.qml:341
137+#: Components/PageHeader.qml:345
138msgid "Recent searches"
138msgid "Recent searches"
139msgstr "Pesquisas recentes"
139msgstr "Pesquisas recentes"
140
140
@@ -154,7 +154,7 @@ msgid_plural "%1 reviews"
154msgstr[0] "%1 análise"
154msgstr[0] "%1 análise"
155msgstr[1] "%1 análises"
155msgstr[1] "%1 análises"
156
156
157−#: Dash/Apps/AppPreview.qml:126
157+#: Dash/Apps/AppPreview.qml:135
158msgid "Rate this"
158msgid "Rate this"
159msgstr "Avaliar isto"
159msgstr "Avaliar isto"
160
160
@@ -174,7 +174,7 @@ msgstr "Enviar"
174msgid "Comments:"
174msgid "Comments:"
175msgstr "Comentários:"
175msgstr "Comentários:"
176
176
177−#: Greeter/Lockscreen.qml:142
177+#: Greeter/Lockscreen.qml:146
178msgid "Emergency Call"
178msgid "Emergency Call"
179msgstr "Chamada de emergência"
179msgstr "Chamada de emergência"
180
180
@@ -207,11 +207,24 @@ msgstr "Fale agora..."
207msgid "Speaking..."
207msgid "Speaking..."
208msgstr "Falando..."
208msgstr "Falando..."
209
209
210+#: Notifications/NotificationMenuItemFactory.qml:89
211+msgid "Show password"
212+msgstr ""
213+
210#: Panel/SearchIndicator.qml:27
214#: Panel/SearchIndicator.qml:27
211msgid "Search"
215msgid "Search"
212msgstr "Pesquisar"
216msgstr "Pesquisar"
213
217
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
215msgid "Sorry, there is nothing that matches your search."
228msgid "Sorry, there is nothing that matches your search."
216msgstr "Desculpe, não há nada que corresponda à sua pesquisa."
229msgstr "Desculpe, não há nada que corresponda à sua pesquisa."
217
230
@@ -219,28 +232,7 @@ msgstr "Desculpe, não há nada que corresponda à sua pesquisa."
219msgid "All"
232msgid "All"
220msgstr ""
233msgstr ""
221
234
222−#: Shell.qml:438
235+#: Shell.qml:441
223#, qt-format
236#, qt-format
224msgid "Please enter %1"
237msgid "Please enter %1"
225msgstr "Por favor, digite %1"
238msgstr "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 ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-06-27 07:53+0000\n"
11"PO-Revision-Date: 2013-06-27 07:53+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Romanian <ro@li.org>\n"
13"Language-Team: Romanian <ro@li.org>\n"
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=3; plural=(n == 1 ? 0: (((n % 100 > 19) || ((n % 100 "
17"Plural-Forms: nplurals=3; plural=(n == 1 ? 0: (((n % 100 > 19) || ((n % 100 "
18"== 0) && (n != 0))) ? 2: 1));\n"
18"== 0) && (n != 0))) ? 2: 1));\n"
19−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
20−"X-Generator: Launchpad (build 16799)\n"
20+"X-Generator: Launchpad (build 16831)\n"
21
21
22#: Applications/applications.js:23
22#: Applications/applications.js:23
23msgid "Phone"
23msgid "Phone"
@@ -87,7 +87,7 @@ msgstr ""
87msgid "YouTube"
87msgid "YouTube"
88msgstr ""
88msgstr ""
89
89
90−#: Components/EdgeDemoOverlay.qml:149
90+#: Components/EdgeDemoOverlay.qml:151
91msgid "Skip intro"
91msgid "Skip intro"
92msgstr ""
92msgstr ""
93
93
@@ -133,7 +133,7 @@ msgid ""
133"phone<br><br>Tap anywhere to start"
133"phone<br><br>Tap anywhere to start"
134msgstr ""
134msgstr ""
135
135
136−#: Components/PageHeader.qml:341
136+#: Components/PageHeader.qml:345
137msgid "Recent searches"
137msgid "Recent searches"
138msgstr "Căutări recente"
138msgstr "Căutări recente"
139
139
@@ -153,7 +153,7 @@ msgid_plural "%1 reviews"
153msgstr[0] ""
153msgstr[0] ""
154msgstr[1] ""
154msgstr[1] ""
155
155
156−#: Dash/Apps/AppPreview.qml:126
156+#: Dash/Apps/AppPreview.qml:135
157msgid "Rate this"
157msgid "Rate this"
158msgstr ""
158msgstr ""
159
159
@@ -173,7 +173,7 @@ msgstr ""
173msgid "Comments:"
173msgid "Comments:"
174msgstr ""
174msgstr ""
175
175
176−#: Greeter/Lockscreen.qml:142
176+#: Greeter/Lockscreen.qml:146
177msgid "Emergency Call"
177msgid "Emergency Call"
178msgstr ""
178msgstr ""
179
179
@@ -206,11 +206,24 @@ msgstr "Vorbiți acum..."
206msgid "Speaking..."
206msgid "Speaking..."
207msgstr "Vorbire..."
207msgstr "Vorbire..."
208
208
209+#: Notifications/NotificationMenuItemFactory.qml:89
210+msgid "Show password"
211+msgstr ""
212+
209#: Panel/SearchIndicator.qml:27
213#: Panel/SearchIndicator.qml:27
210msgid "Search"
214msgid "Search"
211msgstr "Căutare"
215msgstr "Căutare"
212
216
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
214msgid "Sorry, there is nothing that matches your search."
227msgid "Sorry, there is nothing that matches your search."
215msgstr ""
228msgstr ""
216"Ne pare rău, nu este nimic care se potrivește căutării dumneavoastră."
229"Ne pare rău, nu este nimic care se potrivește căutării dumneavoastră."
@@ -219,13 +232,7 @@ msgstr ""
219msgid "All"
232msgid "All"
220msgstr ""
233msgstr ""
221
234
222−#: Shell.qml:438
235+#: Shell.qml:441
223#, qt-format
236#, qt-format
224msgid "Please enter %1"
237msgid "Please enter %1"
225msgstr ""
238msgstr ""
226−
227−#~ msgid "Music"
228−#~ msgstr "Muzică"
229−
230−#~ msgid "Videos"
231−#~ msgstr "Video"
po/ru.po+22−30
@@ -7,7 +7,7 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-10-01 05:55+0000\n"
11"PO-Revision-Date: 2013-10-01 05:55+0000\n"
12"Last-Translator: Zonov Roman <Unknown>\n"
12"Last-Translator: Zonov Roman <Unknown>\n"
13"Language-Team: Russian <ru@li.org>\n"
13"Language-Team: Russian <ru@li.org>\n"
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
17"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
18"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
18"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
20−"X-Generator: Launchpad (build 16799)\n"
20+"X-Generator: Launchpad (build 16831)\n"
21
21
22#: Applications/applications.js:23
22#: Applications/applications.js:23
23msgid "Phone"
23msgid "Phone"
@@ -87,7 +87,7 @@ msgstr "Википедия"
87msgid "YouTube"
87msgid "YouTube"
88msgstr "YouTube"
88msgstr "YouTube"
89
89
90−#: Components/EdgeDemoOverlay.qml:149
90+#: Components/EdgeDemoOverlay.qml:151
91msgid "Skip intro"
91msgid "Skip intro"
92msgstr "Пропустить обучение"
92msgstr "Пропустить обучение"
93
93
@@ -138,7 +138,7 @@ msgid ""
138"phone<br><br>Tap anywhere to start"
138"phone<br><br>Tap anywhere to start"
139msgstr ""
139msgstr ""
140
140
141−#: Components/PageHeader.qml:341
141+#: Components/PageHeader.qml:345
142msgid "Recent searches"
142msgid "Recent searches"
143msgstr "Последние поисковые запросы"
143msgstr "Последние поисковые запросы"
144
144
@@ -157,7 +157,7 @@ msgid "%1 review"
157msgid_plural "%1 reviews"
157msgid_plural "%1 reviews"
158msgstr[0] "%1 отзыв"
158msgstr[0] "%1 отзыв"
159
159
160−#: Dash/Apps/AppPreview.qml:126
160+#: Dash/Apps/AppPreview.qml:135
161msgid "Rate this"
161msgid "Rate this"
162msgstr "Оцените это"
162msgstr "Оцените это"
163
163
@@ -177,7 +177,7 @@ msgstr "Отправить"
177msgid "Comments:"
177msgid "Comments:"
178msgstr "Комментарии:"
178msgstr "Комментарии:"
179
179
180−#: Greeter/Lockscreen.qml:142
180+#: Greeter/Lockscreen.qml:146
181msgid "Emergency Call"
181msgid "Emergency Call"
182msgstr "Экстренный вызов"
182msgstr "Экстренный вызов"
183
183
@@ -210,11 +210,24 @@ msgstr "Говорите..."
210msgid "Speaking..."
210msgid "Speaking..."
211msgstr "Говорите..."
211msgstr "Говорите..."
212
212
213+#: Notifications/NotificationMenuItemFactory.qml:89
214+msgid "Show password"
215+msgstr ""
216+
213#: Panel/SearchIndicator.qml:27
217#: Panel/SearchIndicator.qml:27
214msgid "Search"
218msgid "Search"
215msgstr "Поиск"
219msgstr "Поиск"
216
220
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
218msgid "Sorry, there is nothing that matches your search."
231msgid "Sorry, there is nothing that matches your search."
219msgstr "Извините, поиск не дал результатов."
232msgstr "Извините, поиск не дал результатов."
220
233
@@ -222,28 +235,7 @@ msgstr "Извините, поиск не дал результатов."
222msgid "All"
235msgid "All"
223msgstr ""
236msgstr ""
224
237
225−#: Shell.qml:438
238+#: Shell.qml:441
226#, qt-format
239#, qt-format
227msgid "Please enter %1"
240msgid "Please enter %1"
228msgstr "Пожалуйста, введите %1"
241msgstr "Пожалуйста, введите %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 ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity8\n"
8"Project-Id-Version: unity8\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-10-07 11:46+0000\n"
11"PO-Revision-Date: 2013-10-07 11:46+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Shan <shn@li.org>\n"
13"Language-Team: Shan <shn@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=(n == 1) ? 0 : 1;\n"
17"Plural-Forms: nplurals=2; plural=(n == 1) ? 0 : 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
86msgid "YouTube"
86msgid "YouTube"
87msgstr ""
87msgstr ""
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr ""
137msgstr ""
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr ""
172msgid "Comments:"
172msgid "Comments:"
173msgstr ""
173msgstr ""
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr ""
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr ""
206msgstr ""
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr ""
214msgstr ""
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr ""
227msgstr ""
215
228
@@ -217,7 +230,7 @@ msgstr ""
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr ""
236msgstr ""
po/si.po+22−9
@@ -7,7 +7,7 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-06-26 22:36+0000\n"
11"PO-Revision-Date: 2013-06-26 22:36+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Sinhalese <si@li.org>\n"
13"Language-Team: Sinhalese <si@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
86msgid "YouTube"
86msgid "YouTube"
87msgstr ""
87msgstr ""
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr ""
137msgstr ""
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr ""
172msgid "Comments:"
172msgid "Comments:"
173msgstr ""
173msgstr ""
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr ""
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr ""
206msgstr ""
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr ""
214msgstr ""
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr ""
227msgstr ""
215
228
@@ -217,7 +230,7 @@ msgstr ""
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr ""
236msgstr ""
po/sl.po+22−30
@@ -7,7 +7,7 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-10-02 10:55+0000\n"
11"PO-Revision-Date: 2013-10-02 10:55+0000\n"
12"Last-Translator: Damir Jerovšek <Unknown>\n"
12"Last-Translator: Damir Jerovšek <Unknown>\n"
13"Language-Team: Slovenian <sl@li.org>\n"
13"Language-Team: Slovenian <sl@li.org>\n"
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || "
17"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || "
18"n%100==4 ? 3 : 0);\n"
18"n%100==4 ? 3 : 0);\n"
19−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
20−"X-Generator: Launchpad (build 16799)\n"
20+"X-Generator: Launchpad (build 16831)\n"
21
21
22#: Applications/applications.js:23
22#: Applications/applications.js:23
23msgid "Phone"
23msgid "Phone"
@@ -87,7 +87,7 @@ msgstr "Wikipedija"
87msgid "YouTube"
87msgid "YouTube"
88msgstr "YouTube"
88msgstr "YouTube"
89
89
90−#: Components/EdgeDemoOverlay.qml:149
90+#: Components/EdgeDemoOverlay.qml:151
91msgid "Skip intro"
91msgid "Skip intro"
92msgstr "Preskoči uvod"
92msgstr "Preskoči uvod"
93
93
@@ -137,7 +137,7 @@ msgstr ""
137"Sedaj ste osvojili poteze robov ter lahko začnete uporabljati "
137"Sedaj ste osvojili poteze robov ter lahko začnete uporabljati "
138"telefon<br><br>Tapnite kjerkoli na začetek"
138"telefon<br><br>Tapnite kjerkoli na začetek"
139
139
140−#: Components/PageHeader.qml:341
140+#: Components/PageHeader.qml:345
141msgid "Recent searches"
141msgid "Recent searches"
142msgstr "Nedavna iskanja"
142msgstr "Nedavna iskanja"
143
143
@@ -159,7 +159,7 @@ msgstr[1] "%1 ocena"
159msgstr[2] "%1 oceni"
159msgstr[2] "%1 oceni"
160msgstr[3] "%1 ocene"
160msgstr[3] "%1 ocene"
161
161
162−#: Dash/Apps/AppPreview.qml:126
162+#: Dash/Apps/AppPreview.qml:135
163msgid "Rate this"
163msgid "Rate this"
164msgstr "Ocenite"
164msgstr "Ocenite"
165
165
@@ -179,7 +179,7 @@ msgstr "Pošlji"
179msgid "Comments:"
179msgid "Comments:"
180msgstr "Opombe:"
180msgstr "Opombe:"
181
181
182−#: Greeter/Lockscreen.qml:142
182+#: Greeter/Lockscreen.qml:146
183msgid "Emergency Call"
183msgid "Emergency Call"
184msgstr "Klic v sili"
184msgstr "Klic v sili"
185
185
@@ -212,11 +212,24 @@ msgstr "Govorite zdaj ..."
212msgid "Speaking..."
212msgid "Speaking..."
213msgstr "Govorjenje ..."
213msgstr "Govorjenje ..."
214
214
215+#: Notifications/NotificationMenuItemFactory.qml:89
216+msgid "Show password"
217+msgstr ""
218+
215#: Panel/SearchIndicator.qml:27
219#: Panel/SearchIndicator.qml:27
216msgid "Search"
220msgid "Search"
217msgstr "Iskanje"
221msgstr "Iskanje"
218
222
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
220msgid "Sorry, there is nothing that matches your search."
233msgid "Sorry, there is nothing that matches your search."
221msgstr "Nič se ne ujema z vašim iskalnim nizom."
234msgstr "Nič se ne ujema z vašim iskalnim nizom."
222
235
@@ -224,28 +237,7 @@ msgstr "Nič se ne ujema z vašim iskalnim nizom."
224msgid "All"
237msgid "All"
225msgstr "Vse"
238msgstr "Vse"
226
239
227−#: Shell.qml:438
240+#: Shell.qml:441
228#, qt-format
241#, qt-format
229msgid "Please enter %1"
242msgid "Please enter %1"
230msgstr "Vnesite %1"
243msgstr "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 ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-06-27 09:19+0000\n"
11"PO-Revision-Date: 2013-06-27 09:19+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Serbian <sr@li.org>\n"
13"Language-Team: Serbian <sr@li.org>\n"
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
17"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
18"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
18"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
20−"X-Generator: Launchpad (build 16799)\n"
20+"X-Generator: Launchpad (build 16831)\n"
21
21
22#: Applications/applications.js:23
22#: Applications/applications.js:23
23msgid "Phone"
23msgid "Phone"
@@ -87,7 +87,7 @@ msgstr ""
87msgid "YouTube"
87msgid "YouTube"
88msgstr ""
88msgstr ""
89
89
90−#: Components/EdgeDemoOverlay.qml:149
90+#: Components/EdgeDemoOverlay.qml:151
91msgid "Skip intro"
91msgid "Skip intro"
92msgstr ""
92msgstr ""
93
93
@@ -133,7 +133,7 @@ msgid ""
133"phone<br><br>Tap anywhere to start"
133"phone<br><br>Tap anywhere to start"
134msgstr ""
134msgstr ""
135
135
136−#: Components/PageHeader.qml:341
136+#: Components/PageHeader.qml:345
137msgid "Recent searches"
137msgid "Recent searches"
138msgstr "Скорашње претраге"
138msgstr "Скорашње претраге"
139
139
@@ -153,7 +153,7 @@ msgid_plural "%1 reviews"
153msgstr[0] ""
153msgstr[0] ""
154msgstr[1] ""
154msgstr[1] ""
155
155
156−#: Dash/Apps/AppPreview.qml:126
156+#: Dash/Apps/AppPreview.qml:135
157msgid "Rate this"
157msgid "Rate this"
158msgstr ""
158msgstr ""
159
159
@@ -173,7 +173,7 @@ msgstr ""
173msgid "Comments:"
173msgid "Comments:"
174msgstr ""
174msgstr ""
175
175
176−#: Greeter/Lockscreen.qml:142
176+#: Greeter/Lockscreen.qml:146
177msgid "Emergency Call"
177msgid "Emergency Call"
178msgstr ""
178msgstr ""
179
179
@@ -206,11 +206,24 @@ msgstr "Изговорите сада..."
206msgid "Speaking..."
206msgid "Speaking..."
207msgstr "Говор..."
207msgstr "Говор..."
208
208
209+#: Notifications/NotificationMenuItemFactory.qml:89
210+msgid "Show password"
211+msgstr ""
212+
209#: Panel/SearchIndicator.qml:27
213#: Panel/SearchIndicator.qml:27
210msgid "Search"
214msgid "Search"
211msgstr "Претрага"
215msgstr "Претрага"
212
216
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
214msgid "Sorry, there is nothing that matches your search."
227msgid "Sorry, there is nothing that matches your search."
215msgstr "Нажалост, претрага није наишла на икакво подударање."
228msgstr "Нажалост, претрага није наишла на икакво подударање."
216
229
@@ -218,13 +231,7 @@ msgstr "Нажалост, претрага није наишла на икакв
218msgid "All"
231msgid "All"
219msgstr ""
232msgstr ""
220
233
221−#: Shell.qml:438
234+#: Shell.qml:441
222#, qt-format
235#, qt-format
223msgid "Please enter %1"
236msgid "Please enter %1"
224msgstr ""
237msgstr ""
225−
226−#~ msgid "Music"
227−#~ msgstr "Музика"
228−
229−#~ msgid "Videos"
230−#~ msgstr "Видео"
po/sv.po+22−9
@@ -7,7 +7,7 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-06-26 22:36+0000\n"
11"PO-Revision-Date: 2013-06-26 22:36+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Swedish <sv@li.org>\n"
13"Language-Team: Swedish <sv@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
86msgid "YouTube"
86msgid "YouTube"
87msgstr ""
87msgstr ""
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr ""
137msgstr ""
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr ""
172msgid "Comments:"
172msgid "Comments:"
173msgstr ""
173msgstr ""
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr ""
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr ""
206msgstr ""
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr ""
214msgstr ""
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr ""
227msgstr ""
215
228
@@ -217,7 +230,7 @@ msgstr ""
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr ""
236msgstr ""
po/ta.po+22−9
@@ -7,7 +7,7 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity8\n"
8"Project-Id-Version: unity8\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-10-24 11:36+0000\n"
11"PO-Revision-Date: 2013-10-24 11:36+0000\n"
12"Last-Translator: Thangamani Arun - தங்கமணி அருண் <thangam.arunx@gmail.com>\n"
12"Last-Translator: Thangamani Arun - தங்கமணி அருண் <thangam.arunx@gmail.com>\n"
13"Language-Team: Ubuntu Tamil Team/Free Tamil Computing/Thamizha\n"
13"Language-Team: Ubuntu Tamil Team/Free Tamil Computing/Thamizha\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-25 06:05+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16810)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20"Language: ta\n"
20"Language: ta\n"
21
21
22#: Applications/applications.js:23
22#: Applications/applications.js:23
@@ -87,7 +87,7 @@ msgstr "விக்கிப்பீடியா"
87msgid "YouTube"
87msgid "YouTube"
88msgstr "யூட்யுப்"
88msgstr "யூட்யுப்"
89
89
90−#: Components/EdgeDemoOverlay.qml:149
90+#: Components/EdgeDemoOverlay.qml:151
91msgid "Skip intro"
91msgid "Skip intro"
92msgstr "அறிமுகத்தை தவிர்"
92msgstr "அறிமுகத்தை தவிர்"
93
93
@@ -138,7 +138,7 @@ msgstr ""
138"பயன்படுத்த தொடங்கவும் <br> <br>தட்டுவதன் மூலம் எங்க வேண்டுமானாலும் "
138"பயன்படுத்த தொடங்கவும் <br> <br>தட்டுவதன் மூலம் எங்க வேண்டுமானாலும் "
139"தொடங்கலாம்."
139"தொடங்கலாம்."
140
140
141−#: Components/PageHeader.qml:341
141+#: Components/PageHeader.qml:345
142msgid "Recent searches"
142msgid "Recent searches"
143msgstr "கடையாக தேடப்பட்டவைகள்"
143msgstr "கடையாக தேடப்பட்டவைகள்"
144
144
@@ -158,7 +158,7 @@ msgid_plural "%1 reviews"
158msgstr[0] "%1 பரிசீலனை"
158msgstr[0] "%1 பரிசீலனை"
159msgstr[1] "%1 பரிசீலனைகள்"
159msgstr[1] "%1 பரிசீலனைகள்"
160
160
161−#: Dash/Apps/AppPreview.qml:126
161+#: Dash/Apps/AppPreview.qml:135
162msgid "Rate this"
162msgid "Rate this"
163msgstr "இதை மதிப்பிடு"
163msgstr "இதை மதிப்பிடு"
164
164
@@ -178,7 +178,7 @@ msgstr "அனுப்பு"
178msgid "Comments:"
178msgid "Comments:"
179msgstr "கருத்துகள்:"
179msgstr "கருத்துகள்:"
180
180
181−#: Greeter/Lockscreen.qml:142
181+#: Greeter/Lockscreen.qml:146
182msgid "Emergency Call"
182msgid "Emergency Call"
183msgstr "அவசர அழைப்பு"
183msgstr "அவசர அழைப்பு"
184
184
@@ -211,11 +211,24 @@ msgstr "இப்பொது பேசு..."
211msgid "Speaking..."
211msgid "Speaking..."
212msgstr "பேசுகிறது..."
212msgstr "பேசுகிறது..."
213
213
214+#: Notifications/NotificationMenuItemFactory.qml:89
215+msgid "Show password"
216+msgstr ""
217+
214#: Panel/SearchIndicator.qml:27
218#: Panel/SearchIndicator.qml:27
215msgid "Search"
219msgid "Search"
216msgstr "தெடு"
220msgstr "தெடு"
217
221
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
219msgid "Sorry, there is nothing that matches your search."
232msgid "Sorry, there is nothing that matches your search."
220msgstr "மன்னிக்கவும், உங்களுடைய தேடலுக்கு தகுந்த பொருத்தம் கிடைக்கவில்லை."
233msgstr "மன்னிக்கவும், உங்களுடைய தேடலுக்கு தகுந்த பொருத்தம் கிடைக்கவில்லை."
221
234
@@ -223,7 +236,7 @@ msgstr "மன்னிக்கவும், உங்களுடைய தே
223msgid "All"
236msgid "All"
224msgstr "அனைத்தும்"
237msgstr "அனைத்தும்"
225
238
226−#: Shell.qml:438
239+#: Shell.qml:441
227#, qt-format
240#, qt-format
228msgid "Please enter %1"
241msgid "Please enter %1"
229msgstr "தயவுச்செய்து %1 உள்ளிடு"
242msgstr "தயவுச்செய்து %1 உள்ளிடு"
po/te.po+22−12
@@ -7,7 +7,7 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-06-27 09:57+0000\n"
11"PO-Revision-Date: 2013-06-27 09:57+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Telugu <te@li.org>\n"
13"Language-Team: Telugu <te@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
86msgid "YouTube"
86msgid "YouTube"
87msgstr ""
87msgstr ""
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr ""
137msgstr ""
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr ""
172msgid "Comments:"
172msgid "Comments:"
173msgstr ""
173msgstr ""
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr ""
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr ""
206msgstr ""
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr ""
214msgstr ""
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr ""
227msgstr ""
215
228
@@ -217,10 +230,7 @@ msgstr ""
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr ""
236msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "సంగీతం"
po/tr.po+22−30
@@ -7,7 +7,7 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-10-01 13:21+0000\n"
11"PO-Revision-Date: 2013-10-01 13:21+0000\n"
12"Last-Translator: Volkan Gezer <Unknown>\n"
12"Last-Translator: Volkan Gezer <Unknown>\n"
13"Language-Team: Turkish <tr@li.org>\n"
13"Language-Team: Turkish <tr@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Vikipedi"
86msgid "YouTube"
86msgid "YouTube"
87msgstr "YouTube"
87msgstr "YouTube"
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr "İntro'yu geç"
91msgstr "İntro'yu geç"
92
92
@@ -133,7 +133,7 @@ msgid ""
133"phone<br><br>Tap anywhere to start"
133"phone<br><br>Tap anywhere to start"
134msgstr ""
134msgstr ""
135
135
136−#: Components/PageHeader.qml:341
136+#: Components/PageHeader.qml:345
137msgid "Recent searches"
137msgid "Recent searches"
138msgstr "Son Arananlar"
138msgstr "Son Arananlar"
139
139
@@ -153,7 +153,7 @@ msgid_plural "%1 reviews"
153msgstr[0] "%1 inceleme"
153msgstr[0] "%1 inceleme"
154msgstr[1] "%1 inceleme"
154msgstr[1] "%1 inceleme"
155
155
156−#: Dash/Apps/AppPreview.qml:126
156+#: Dash/Apps/AppPreview.qml:135
157msgid "Rate this"
157msgid "Rate this"
158msgstr "Oyla"
158msgstr "Oyla"
159
159
@@ -173,7 +173,7 @@ msgstr "Gönder"
173msgid "Comments:"
173msgid "Comments:"
174msgstr "Yorumlar:"
174msgstr "Yorumlar:"
175
175
176−#: Greeter/Lockscreen.qml:142
176+#: Greeter/Lockscreen.qml:146
177msgid "Emergency Call"
177msgid "Emergency Call"
178msgstr "Acil Arama"
178msgstr "Acil Arama"
179
179
@@ -206,11 +206,24 @@ msgstr "Şimdi Konuşun..."
206msgid "Speaking..."
206msgid "Speaking..."
207msgstr "Konuşuyor..."
207msgstr "Konuşuyor..."
208
208
209+#: Notifications/NotificationMenuItemFactory.qml:89
210+msgid "Show password"
211+msgstr ""
212+
209#: Panel/SearchIndicator.qml:27
213#: Panel/SearchIndicator.qml:27
210msgid "Search"
214msgid "Search"
211msgstr "Ara"
215msgstr "Ara"
212
216
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
214msgid "Sorry, there is nothing that matches your search."
227msgid "Sorry, there is nothing that matches your search."
215msgstr "Üzgünüz, aramanızla eşleşen hiçbir şey yok."
228msgstr "Üzgünüz, aramanızla eşleşen hiçbir şey yok."
216
229
@@ -218,28 +231,7 @@ msgstr "Üzgünüz, aramanızla eşleşen hiçbir şey yok."
218msgid "All"
231msgid "All"
219msgstr ""
232msgstr ""
220
233
221−#: Shell.qml:438
234+#: Shell.qml:441
222#, qt-format
235#, qt-format
223msgid "Please enter %1"
236msgid "Please enter %1"
224msgstr "Lütfen %1 girin"
237msgstr "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 ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-10-09 22:38+0000\n"
11"PO-Revision-Date: 2013-10-09 22:38+0000\n"
12"Last-Translator: Gheyret T.Kenji <Unknown>\n"
12"Last-Translator: Gheyret T.Kenji <Unknown>\n"
13"Language-Team: Uyghur <ug@li.org>\n"
13"Language-Team: Uyghur <ug@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "ۋىكىپېدىيە"
86msgid "YouTube"
86msgid "YouTube"
87msgstr "YouTube"
87msgstr "YouTube"
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr "يېقىنقى ئىزدەشلەر"
137msgstr "يېقىنقى ئىزدەشلەر"
138
138
@@ -151,7 +151,7 @@ msgid "%1 review"
151msgid_plural "%1 reviews"
151msgid_plural "%1 reviews"
152msgstr[0] "%1 باھا"
152msgstr[0] "%1 باھا"
153
153
154−#: Dash/Apps/AppPreview.qml:126
154+#: Dash/Apps/AppPreview.qml:135
155msgid "Rate this"
155msgid "Rate this"
156msgstr ""
156msgstr ""
157
157
@@ -171,7 +171,7 @@ msgstr "ئەۋەت"
171msgid "Comments:"
171msgid "Comments:"
172msgstr "ئىنكاس:"
172msgstr "ئىنكاس:"
173
173
174−#: Greeter/Lockscreen.qml:142
174+#: Greeter/Lockscreen.qml:146
175msgid "Emergency Call"
175msgid "Emergency Call"
176msgstr ""
176msgstr ""
177
177
@@ -204,11 +204,24 @@ msgstr "ئەمدى سۆزلەڭ…"
204msgid "Speaking..."
204msgid "Speaking..."
205msgstr "سۆزلەۋاتىسىز…"
205msgstr "سۆزلەۋاتىسىز…"
206
206
207+#: Notifications/NotificationMenuItemFactory.qml:89
208+msgid "Show password"
209+msgstr ""
210+
207#: Panel/SearchIndicator.qml:27
211#: Panel/SearchIndicator.qml:27
208msgid "Search"
212msgid "Search"
209msgstr "ئىزدە"
213msgstr "ئىزدە"
210
214
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
212msgid "Sorry, there is nothing that matches your search."
225msgid "Sorry, there is nothing that matches your search."
213msgstr "كەچۈرۈڭ، ئىزدىگىنىڭىزگە ماس نەتىجە تېپىلمىدى."
226msgstr "كەچۈرۈڭ، ئىزدىگىنىڭىزگە ماس نەتىجە تېپىلمىدى."
214
227
@@ -216,22 +229,7 @@ msgstr "كەچۈرۈڭ، ئىزدىگىنىڭىزگە ماس نەتىجە تېپ
216msgid "All"
229msgid "All"
217msgstr "ھەممىسى"
230msgstr "ھەممىسى"
218
231
219−#: Shell.qml:438
232+#: Shell.qml:441
220#, qt-format
233#, qt-format
221msgid "Please enter %1"
234msgid "Please enter %1"
222msgstr "%1 نى كىرگۈزۈڭ"
235msgstr "%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+24−11
@@ -7,17 +7,17 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11−"PO-Revision-Date: 2013-10-19 16:44+0000\n"
11+"PO-Revision-Date: 2013-11-23 12:37+0000\n"
12−"Last-Translator: Yuri Chornoivan <yurchor@gmail.com>\n"
12+"Last-Translator: Ignat Kizenko <Unknown>\n"
13"Language-Team: Ukrainian <uk@li.org>\n"
13"Language-Team: Ukrainian <uk@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
17"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
18"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
18"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2013-10-20 05:20+0000\n"
19+"X-Launchpad-Export-Date: 2013-11-24 05:50+0000\n"
20−"X-Generator: Launchpad (build 16807)\n"
20+"X-Generator: Launchpad (build 16831)\n"
21
21
22#: Applications/applications.js:23
22#: Applications/applications.js:23
23msgid "Phone"
23msgid "Phone"
@@ -87,7 +87,7 @@ msgstr "Вікіпедія"
87msgid "YouTube"
87msgid "YouTube"
88msgstr "YouTube"
88msgstr "YouTube"
89
89
90−#: Components/EdgeDemoOverlay.qml:149
90+#: Components/EdgeDemoOverlay.qml:151
91msgid "Skip intro"
91msgid "Skip intro"
92msgstr "Пропустити вступ"
92msgstr "Пропустити вступ"
93
93
@@ -138,7 +138,7 @@ msgstr ""
138"Тепер жести налаштовано, ви можете почати користуватися "
138"Тепер жести налаштовано, ви можете почати користуватися "
139"телефоном.<br><br>Натисніть у довільному місці екрана."
139"телефоном.<br><br>Натисніть у довільному місці екрана."
140
140
141−#: Components/PageHeader.qml:341
141+#: Components/PageHeader.qml:345
142msgid "Recent searches"
142msgid "Recent searches"
143msgstr "Нещодавні пошуки"
143msgstr "Нещодавні пошуки"
144
144
@@ -159,7 +159,7 @@ msgstr[0] "%1 рецензія"
159msgstr[1] "%1 рецензії"
159msgstr[1] "%1 рецензії"
160msgstr[2] "%1 рецензій"
160msgstr[2] "%1 рецензій"
161
161
162−#: Dash/Apps/AppPreview.qml:126
162+#: Dash/Apps/AppPreview.qml:135
163msgid "Rate this"
163msgid "Rate this"
164msgstr "Оцінити"
164msgstr "Оцінити"
165
165
@@ -179,7 +179,7 @@ msgstr "Надіслати"
179msgid "Comments:"
179msgid "Comments:"
180msgstr "Коментарі:"
180msgstr "Коментарі:"
181
181
182−#: Greeter/Lockscreen.qml:142
182+#: Greeter/Lockscreen.qml:146
183msgid "Emergency Call"
183msgid "Emergency Call"
184msgstr "Терміновий виклик"
184msgstr "Терміновий виклик"
185
185
@@ -212,11 +212,24 @@ msgstr "Можна говорити…"
212msgid "Speaking..."
212msgid "Speaking..."
213msgstr "Мовлення…"
213msgstr "Мовлення…"
214
214
215+#: Notifications/NotificationMenuItemFactory.qml:89
216+msgid "Show password"
217+msgstr "Показати пароль"
218+
215#: Panel/SearchIndicator.qml:27
219#: Panel/SearchIndicator.qml:27
216msgid "Search"
220msgid "Search"
217msgstr "Пошук"
221msgstr "Пошук"
218
222
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
220msgid "Sorry, there is nothing that matches your search."
233msgid "Sorry, there is nothing that matches your search."
221msgstr "Вибачте, для вказаних вами ключових слів нічого не знайдено."
234msgstr "Вибачте, для вказаних вами ключових слів нічого не знайдено."
222
235
@@ -224,7 +237,7 @@ msgstr "Вибачте, для вказаних вами ключових слі
224msgid "All"
237msgid "All"
225msgstr "Усе"
238msgstr "Усе"
226
239
227−#: Shell.qml:438
240+#: Shell.qml:441
228#, qt-format
241#, qt-format
229msgid "Please enter %1"
242msgid "Please enter %1"
230msgstr "Будь ласка, введіть %1"
243msgstr "Будь ласка, введіть %1"
po/unity8.pot+20−7
@@ -8,7 +8,7 @@ msgid ""
8msgstr ""
8msgstr ""
9"Project-Id-Version: unity8\n"
9"Project-Id-Version: unity8\n"
10"Report-Msgid-Bugs-To: \n"
10"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"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -86,7 +86,7 @@ msgstr ""
86msgid "YouTube"
86msgid "YouTube"
87msgstr ""
87msgstr ""
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr ""
137msgstr ""
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr ""
172msgid "Comments:"
172msgid "Comments:"
173msgstr ""
173msgstr ""
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr ""
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr ""
206msgstr ""
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr ""
214msgstr ""
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr ""
227msgstr ""
215
228
@@ -217,7 +230,7 @@ msgstr ""
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr ""
236msgstr ""
po/xh.po+22−9
@@ -7,7 +7,7 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity8\n"
8"Project-Id-Version: unity8\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-09-28 13:20+0000\n"
11"PO-Revision-Date: 2013-09-28 13:20+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Xhosa <xh@li.org>\n"
13"Language-Team: Xhosa <xh@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
86msgid "YouTube"
86msgid "YouTube"
87msgstr ""
87msgstr ""
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr ""
137msgstr ""
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr ""
172msgid "Comments:"
172msgid "Comments:"
173msgstr ""
173msgstr ""
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr ""
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr ""
206msgstr ""
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr ""
214msgstr ""
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr ""
227msgstr ""
215
228
@@ -217,7 +230,7 @@ msgstr ""
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr ""
236msgstr ""
po/zh_CN.po+22−30
@@ -7,7 +7,7 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-10-09 13:51+0000\n"
11"PO-Revision-Date: 2013-10-09 13:51+0000\n"
12"Last-Translator: Aron Xu <Unknown>\n"
12"Last-Translator: Aron Xu <Unknown>\n"
13"Language-Team: Chinese (Simplified) <zh_CN@li.org>\n"
13"Language-Team: Chinese (Simplified) <zh_CN@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "维基百科"
86msgid "YouTube"
86msgid "YouTube"
87msgstr "YouTube"
87msgstr "YouTube"
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr "近期搜索"
137msgstr "近期搜索"
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr ""
172msgid "Comments:"
172msgid "Comments:"
173msgstr ""
173msgstr ""
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr "现在请讲..."
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr "讲话中..."
206msgstr "讲话中..."
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr "搜索"
214msgstr "搜索"
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr "对不起,没有找到您想要的结果。"
227msgstr "对不起,没有找到您想要的结果。"
215
228
@@ -217,28 +230,7 @@ msgstr "对不起,没有找到您想要的结果。"
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr ""
236msgstr ""
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 ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11"PO-Revision-Date: 2013-06-27 10:24+0000\n"
11"PO-Revision-Date: 2013-06-27 10:24+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Chinese (Traditional) <zh_TW@li.org>\n"
13"Language-Team: Chinese (Traditional) <zh_TW@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
19+"X-Generator: Launchpad (build 16831)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
86msgid "YouTube"
86msgid "YouTube"
87msgstr ""
87msgstr ""
88
88
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
90msgid "Skip intro"
90msgid "Skip intro"
91msgstr ""
91msgstr ""
92
92
@@ -132,7 +132,7 @@ msgid ""
132"phone<br><br>Tap anywhere to start"
132"phone<br><br>Tap anywhere to start"
133msgstr ""
133msgstr ""
134
134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136msgid "Recent searches"
136msgid "Recent searches"
137msgstr "最近搜尋"
137msgstr "最近搜尋"
138
138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152msgstr[0] ""
152msgstr[0] ""
153msgstr[1] ""
153msgstr[1] ""
154
154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156msgid "Rate this"
156msgid "Rate this"
157msgstr ""
157msgstr ""
158
158
@@ -172,7 +172,7 @@ msgstr ""
172msgid "Comments:"
172msgid "Comments:"
173msgstr ""
173msgstr ""
174
174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176msgid "Emergency Call"
176msgid "Emergency Call"
177msgstr ""
177msgstr ""
178
178
@@ -205,11 +205,24 @@ msgstr "請說..."
205msgid "Speaking..."
205msgid "Speaking..."
206msgstr "說話中..."
206msgstr "說話中..."
207
207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208#: Panel/SearchIndicator.qml:27
212#: Panel/SearchIndicator.qml:27
209msgid "Search"
213msgid "Search"
210msgstr "搜尋"
214msgstr "搜尋"
211
215
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
213msgid "Sorry, there is nothing that matches your search."
226msgid "Sorry, there is nothing that matches your search."
214msgstr "很抱歉,找不到符合您想搜尋的結果。"
227msgstr "很抱歉,找不到符合您想搜尋的結果。"
215
228
@@ -217,13 +230,7 @@ msgstr "很抱歉,找不到符合您想搜尋的結果。"
217msgid "All"
230msgid "All"
218msgstr ""
231msgstr ""
219
232
220−#: Shell.qml:438
233+#: Shell.qml:441
221#, qt-format
234#, qt-format
222msgid "Please enter %1"
235msgid "Please enter %1"
223msgstr ""
236msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "音樂"
227−
228−#~ msgid "Videos"
229−#~ msgstr "影片"
run+2
@@ -42,6 +42,8 @@ done
42if $FAKE; then
42if $FAKE; then
43 export QML2_IMPORT_PATH=$PWD/builddir/tests/mocks:$PWD/builddir/plugins:$PWD/builddir/modules
43 export QML2_IMPORT_PATH=$PWD/builddir/tests/mocks:$PWD/builddir/plugins:$PWD/builddir/modules
44 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/libusermetrics:$PWD/builddir/tests/mocks/LightDM/single
44 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/libusermetrics:$PWD/builddir/tests/mocks/LightDM/single
45+else
46+ export QML2_IMPORT_PATH=`pkg-config --variable=plugindir unity-shell-api`
45fi
47fi
46
48
47if $PINLOCK; then
49if $PINLOCK; then
run_on_device+1−1
@@ -76,7 +76,7 @@ setup_adb_forwarding() {
76
76
77install_dependencies() {
77install_dependencies() {
78 exec_with_adb apt-get update
78 exec_with_adb apt-get update
79− exec_with_ssh $SUDO apt-get -y install build-essential rsync bzr ccache gdb ninja-build devscripts equivs
79+ exec_with_ssh $SUDO apt-get -y install build-essential rsync bzr ccache gdb ninja-build devscripts equivs unity-plugin-scopes
80}
80}
81
81
82sync_code() {
82sync_code() {
tests/autopilot/unity8/process_helpers.py+65−38
@@ -21,18 +21,25 @@ from autopilot.introspection import (
21 get_proxy_object_for_existing_process,
21 get_proxy_object_for_existing_process,
22 ProcessSearchError,
22 ProcessSearchError,
23)
23)
24+import logging
24import subprocess
25import subprocess
25from unity8.shell.emulators import UnityEmulatorBase
26from unity8.shell.emulators import UnityEmulatorBase
26from unity8.shell.emulators.main_window import MainWindow
27from unity8.shell.emulators.main_window import MainWindow
27
28
29+logger = logging.getLogger(__name__)
30+
28
31
29class CannotAccessUnity(Exception):
32class CannotAccessUnity(Exception):
30 pass
33 pass
31
34
32
35
33−def unlock_unity():
36+def unlock_unity(unity_proxy_obj=None):
34 """Helper function that attempts to unlock the unity greeter.
37 """Helper function that attempts to unlock the unity greeter.
35
38
39+ If unity_proxy_object is None create a proxy object by querying for the
40+ running unity process.
41+ Otherwise re-use the passed proxy object.
42+
36 :raises RuntimeError: if the greeter attempts and fails to be unlocked.
43 :raises RuntimeError: if the greeter attempts and fails to be unlocked.
37
44
38 :raises RuntimeWarning: when the greeter cannot be found because it is
45 :raises RuntimeWarning: when the greeter cannot be found because it is
@@ -43,30 +50,42 @@ def unlock_unity():
43 upstart job cannot be found at all.
50 upstart job cannot be found at all.
44
51
45 """
52 """
46− pid = _get_unity_pid()
47− try:
48− unity = get_proxy_object_for_existing_process(
49− pid=pid,
50− emulator_base=UnityEmulatorBase,
51− )
52− main_window = MainWindow(unity)
53−
54− greeter = main_window.get_greeter()
55− if greeter is None:
53+ if unity_proxy_obj is None:
56− raise RuntimeWarning("Greeter appears to be already unlocked.")
54+ try:
57− greeter.swipe()
55+ pid = _get_unity_pid()
56+ unity = _get_unity_proxy_object(pid)
57+ main_window = MainWindow(unity)
58− except ProcessSearchError as e:
58+ except ProcessSearchError as e:
59− raise CannotAccessUnity(
59+ raise CannotAccessUnity(
60− "Cannot introspect unity, make sure that it has been started "
60+ "Cannot introspect unity, make sure that it has been started "
61− "with testability. Perhaps use the function "
61+ "with testability. Perhaps use the function "
62− "'restart_unity_with_testability' this module provides."
62+ "'restart_unity_with_testability' this module provides."
63− "(%s)"
63+ "(%s)"
64− % str(e)
64+ % str(e)
65− )
65+ )
66+ else:
67+ main_window = MainWindow(unity_proxy_obj)
68+
69+ greeter = main_window.get_greeter()
70+ if greeter.created == False:
71+ raise RuntimeWarning("Greeter appears to be already unlocked.")
72+ greeter.swipe()
73+
74+
75+def restart_unity_with_testability(*args):
76+ """Restarts (or starts) unity with testability enabled.
77+
78+ Passes *args arguments to the launched process.
79+
80+ """
81+ args += ("QT_LOAD_TESTABILITY=1",)
82+ return restart_unity(*args)
83+
66
84
85+def restart_unity(*args):
86+ """Restarts (or starts) unity8 using the provided arguments.
67
87
68−def restart_unity_with_testability():
88+ Passes *args arguments to the launched process.
69− """Restarts (or just starts) unity8 with the testability driver loaded
70
89
71 :raises subprocess.CalledProcessError: if unable to stop or start the
90 :raises subprocess.CalledProcessError: if unable to stop or start the
72 unity8 upstart job.
91 unity8 upstart job.
@@ -75,27 +94,28 @@ def restart_unity_with_testability():
75 status = _get_unity_status()
94 status = _get_unity_status()
76 if "start/" in status:
95 if "start/" in status:
77 try:
96 try:
78− print("Stopping unity.")
97+ output = subprocess.check_output(['initctl', 'stop', 'unity8'])
79− subprocess.check_call([
98+ logger.info(output)
80− 'initctl',
81− 'stop',
82− 'unity8',
83− ])
84 except subprocess.CalledProcessError as e:
99 except subprocess.CalledProcessError as e:
100+ e.args += (
85− e.args += ("Failed to stop running instance of unity8", )
101+ "Failed to stop running instance of unity8: %s" % e.output,
102+ )
86 raise
103 raise
87
104
88 try:
105 try:
89− print("Starting unity with testability.")
106+ command = ['initctl', 'start', 'unity8'] + list(args)
90− subprocess.check_call([
107+ output = subprocess.check_output(
91− 'initctl',
108+ command,
92− 'start',
109+ stderr=subprocess.STDOUT,
93− 'unity8',
110+ universal_newlines=True,
94− 'QT_LOAD_TESTABILITY=1',
111+ )
95− ])
112+ logger.info(output)
113+ pid = _get_unity_pid()
96 except subprocess.CalledProcessError as e:
114 except subprocess.CalledProcessError as e:
97− e.args += ("Failed to start unity8 with testability ", )
115+ e.args += ("Failed to start unity8: %s" % e.output,)
98 raise
116 raise
117+ else:
118+ return _get_unity_proxy_object(pid)
99
119
100
120
101def _get_unity_status():
121def _get_unity_status():
@@ -114,3 +134,10 @@ def _get_unity_pid():
114 if not "start/" in status:
134 if not "start/" in status:
115 raise CannotAccessUnity("Unity is not in the running state.")
135 raise CannotAccessUnity("Unity is not in the running state.")
116 return int(status.split()[-1])
136 return int(status.split()[-1])
137+
138+
139+def _get_unity_proxy_object(pid):
140+ return get_proxy_object_for_existing_process(
141+ pid=pid,
142+ emulator_base=UnityEmulatorBase,
143+ )
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 @@
18#
18#
19
19
20from unity8.shell.emulators import UnityEmulatorBase
20from unity8.shell.emulators import UnityEmulatorBase
21−from time import sleep
21+
22
22
23class Dash(UnityEmulatorBase):
23class Dash(UnityEmulatorBase):
24
24
25 """An emulator that understands the Dash."""
25 """An emulator that understands the Dash."""
26
26
27 def get_home_applications_grid(self):
27 def get_home_applications_grid(self):
28− for i in range(1,10):
29− get_grid = self.get_scope('home').select_single(
28+ get_grid = self.get_scope('home').wait_select_single(
30− "GenericFilterGrid",
29+ "GenericFilterGrid",
31− objectName="applications.scope"
30+ objectName="applications.scope"
32− )
31+ )
33− if get_grid != None:
34− break
35− sleep(1)
36 return get_grid
32 return get_grid
37
33
38 def get_application_icon(self, text):
34 def get_application_icon(self, text):
39 """Returns a 'Tile' icon that has the text 'text' from the application
35 """Returns a 'Tile' icon that has the text 'text' from the application
40 grid.
36 grid.
41
37
42− Will return None if the icon isn't found.
43−
44 :param text: String containing the text of the icon to search for.
38 :param text: String containing the text of the icon to search for.
45
39
46 """
40 """
47 app_grid = self.get_home_applications_grid()
41 app_grid = self.get_home_applications_grid()
48− for i in range(1,10):
49− resp_grid = app_grid.select_single('ResponsiveGridView')
42+ resp_grid = app_grid.wait_select_single('ResponsiveGridView')
50− if resp_grid != None:
51− break
52− sleep(1)
53 return resp_grid.select_single('Tile', text=text)
43 return resp_grid.select_single('Tile', text=text)
54
44
55 def get_scope(self, scope_name='home'):
45 def get_scope(self, scope_name='home'):
56− dash_content = self.select_single(
46+ dash_content = self.wait_select_single(
57 'QQuickListView',
47 'QQuickListView',
58 objectName='dashContentList'
48 objectName='dashContentList'
59 )
49 )
tests/autopilot/unity8/shell/emulators/hud.py+12−4
@@ -26,6 +26,7 @@ from autopilot.input import Touch
26
26
27SwipeCoords = namedtuple('SwipeCoords', 'start_x end_x start_y end_y')
27SwipeCoords = namedtuple('SwipeCoords', 'start_x end_x start_y end_y')
28
28
29+
29class Hud(UnityEmulatorBase, DragMixin):
30class Hud(UnityEmulatorBase, DragMixin):
30
31
31 """An emulator that understands the Hud."""
32 """An emulator that understands the Hud."""
@@ -34,13 +35,18 @@ class Hud(UnityEmulatorBase, DragMixin):
34 """Swipes open the Hud."""
35 """Swipes open the Hud."""
35 self.touch = Touch.create()
36 self.touch = Touch.create()
36
37
37− window = self.get_root_instance().select_single('QQuickView')
38+ window = self.get_root_instance().wait_select_single('QQuickView')
38− hud_show_button = window.select_single("HudButton")
39+ hud_show_button = window.wait_select_single("HudButton")
39
40
40 swipe_coords = self.get_button_swipe_coords(window, hud_show_button)
41 swipe_coords = self.get_button_swipe_coords(window, hud_show_button)
41
42
42 self.touch.press(swipe_coords.start_x, swipe_coords.start_y)
43 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+ )
44 try:
50 try:
45 hud_show_button.opacity.wait_for(1.0)
51 hud_show_button.opacity.wait_for(1.0)
46 self.touch.release()
52 self.touch.release()
@@ -74,6 +80,8 @@ class Hud(UnityEmulatorBase, DragMixin):
74 start_x = int(main_view.x + (main_view.width / 2))
80 start_x = int(main_view.x + (main_view.width / 2))
75 end_x = start_x
81 end_x = start_x
76 start_y = main_view.y + (main_view.height - 3)
82 start_y = main_view.y + (main_view.height - 3)
83+ end_y = main_view.y + int(
77− end_y = main_view.y + int(hud_show_button.y + (hud_show_button.height/2))
84+ hud_show_button.y + (hud_show_button.height/2)
85+ )
78
86
79 return SwipeCoords(start_x, end_x, start_y, end_y)
87 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):
38 return self.app.select_single(Greeter)
38 return self.app.select_single(Greeter)
39
39
40 def get_greeter_content_loader(self):
40 def get_greeter_content_loader(self):
41− return self.app.select_single(
41+ return self.app.wait_select_single(
42 "QQuickLoader",
42 "QQuickLoader",
43 objectName="greeterContentLoader"
43 objectName="greeterContentLoader"
44 )
44 )
45
45
46+ def get_greeter_background(self):
47+ return self.app.select_single("CrossFadeImage", objectName="greeterBackground")
48+
46 def get_login_loader(self):
49 def get_login_loader(self):
47 return self.app.select_single("QQuickLoader", objectName="loginLoader")
50 return self.app.select_single("QQuickLoader", objectName="loginLoader")
48
51
@@ -64,12 +67,6 @@ class MainWindow(object):
64 def get_dash(self):
67 def get_dash(self):
65 return self.app.select_single(Dash)
68 return self.app.select_single(Dash)
66
69
67− def get_dash_home_applications_grid(self):
68− return self.app.select_single(
69− "ApplicationsFilterGrid",
70− objectName="dashHomeApplicationsGrid"
71− )
72−
73 def get_bottombar(self):
70 def get_bottombar(self):
74 return self.app.select_single("Bottombar")
71 return self.app.select_single("Bottombar")
75
72
@@ -99,3 +96,6 @@ class MainWindow(object):
99 'DefaultIndicatorWidget',
96 'DefaultIndicatorWidget',
100 objectName=indicator_name+'-widget'
97 objectName=indicator_name+'-widget'
101 )
98 )
99+
100+ def get_shell_background(self):
101+ return self.app.select_single("CrossFadeImage", objectName="backgroundImage")
tests/autopilot/unity8/shell/tests/__init__.py+54−36
@@ -28,13 +28,12 @@ from autopilot.platform import model
28from autopilot.testcase import AutopilotTestCase
28from autopilot.testcase import AutopilotTestCase
29from autopilot.matchers import Eventually
29from autopilot.matchers import Eventually
30from autopilot.input import Touch
30from autopilot.input import Touch
31−from autopilot.introspection import get_proxy_object_for_existing_process
32from autopilot.display import Display
31from autopilot.display import Display
33import logging
32import logging
34import os.path
33import os.path
35import subprocess
34import subprocess
36import sys
35import sys
37−from testtools.matchers import Equals, NotEquals
36+from testtools.matchers import Equals
38
37
39from unity8 import (
38from unity8 import (
40 get_lib_path,
39 get_lib_path,
@@ -43,7 +42,7 @@ from unity8 import (
43 get_default_extra_mock_libraries,
42 get_default_extra_mock_libraries,
44 get_data_dirs
43 get_data_dirs
45)
44)
46−from unity8.shell.emulators import UnityEmulatorBase
45+from unity8.process_helpers import restart_unity_with_testability
47from unity8.shell.emulators.dash import Dash
46from unity8.shell.emulators.dash import Dash
48from unity8.shell.emulators.main_window import MainWindow
47from unity8.shell.emulators.main_window import MainWindow
49
48
@@ -53,7 +52,7 @@ logger = logging.getLogger(__name__)
53UNITYSHELL_GSETTINGS_SCHEMA = "org.compiz.unityshell"
52UNITYSHELL_GSETTINGS_SCHEMA = "org.compiz.unityshell"
54UNITYSHELL_GSETTINGS_PATH = "/org/compiz/profiles/unity/plugins/unityshell/"
53UNITYSHELL_GSETTINGS_PATH = "/org/compiz/profiles/unity/plugins/unityshell/"
55UNITYSHELL_LAUNCHER_KEY = "launcher-hide-mode"
54UNITYSHELL_LAUNCHER_KEY = "launcher-hide-mode"
56−UNITYSHELL_LAUNCHER_MODE = 1 # launcher hidden
55+UNITYSHELL_LAUNCHER_MODE = 1 # launcher hidden
57
56
58
57
59def _get_device_emulation_scenarios(devices='All'):
58def _get_device_emulation_scenarios(devices='All'):
@@ -93,17 +92,25 @@ class UnityTestCase(AutopilotTestCase):
93 ], stderr=subprocess.STDOUT)
92 ], stderr=subprocess.STDOUT)
94 except subprocess.CalledProcessError, e:
93 except subprocess.CalledProcessError, e:
95 sys.stderr.write(
94 sys.stderr.write(
96− "Error: `initctl status unity8` failed, most probably the unity8 session could not be found:\n\n"
95+ "Error: `initctl status unity8` failed, most probably the "
96+ "unity8 session could not be found:\n\n"
97 "{0}\n"
97 "{0}\n"
98− "Please install unity8 or copy data/unity8.conf to {1}\n".format(
98+ "Please install unity8 or copy data/unity8.conf to "
99+ "{1}\n".format(
99 e.output,
100 e.output,
100− os.path.join(os.getenv("XDG_CONFIG_HOME", os.path.join(os.getenv("HOME"), ".config")), "upstart")
101+ os.path.join(os.getenv("XDG_CONFIG_HOME",
102+ os.path.join(os.getenv("HOME"),
103+ ".config")
104+ ),
105+ "upstart")
106+ )
101− ))
107+ )
102 sys.exit(1)
108 sys.exit(1)
103
109
104 if "start/" in output:
110 if "start/" in output:
105 sys.stderr.write(
111 sys.stderr.write(
106− "Error: Unity is currently running, these tests require it to be 'stopped'.\n"
112+ "Error: Unity is currently running, these tests require it to "
113+ "be 'stopped'.\n"
107 "Please run this command before running these tests: \n"
114 "Please run this command before running these tests: \n"
108 "initctl stop unity8\n"
115 "initctl stop unity8\n"
109 )
116 )
@@ -111,11 +118,22 @@ class UnityTestCase(AutopilotTestCase):
111
118
112 def setUp(self):
119 def setUp(self):
113 super(UnityTestCase, self).setUp()
120 super(UnityTestCase, self).setUp()
121+ if (Gio is not None and
122+ UNITYSHELL_GSETTINGS_SCHEMA in
114− if Gio is not None and UNITYSHELL_GSETTINGS_SCHEMA in Gio.Settings.list_relocatable_schemas():
123+ Gio.Settings.list_relocatable_schemas()):
124+
115 # Hide Unity launcher
125 # Hide Unity launcher
116− self._unityshell_schema = Gio.Settings.new_with_path(UNITYSHELL_GSETTINGS_SCHEMA, UNITYSHELL_GSETTINGS_PATH)
126+ self._unityshell_schema = Gio.Settings.new_with_path(
127+ UNITYSHELL_GSETTINGS_SCHEMA,
128+ UNITYSHELL_GSETTINGS_PATH,
129+ )
117− self._launcher_hide_mode = self._unityshell_schema.get_int(UNITYSHELL_LAUNCHER_KEY)
130+ self._launcher_hide_mode = self._unityshell_schema.get_int(
131+ UNITYSHELL_LAUNCHER_KEY,
132+ )
118− self._unityshell_schema.set_int(UNITYSHELL_LAUNCHER_KEY, UNITYSHELL_LAUNCHER_MODE)
133+ self._unityshell_schema.set_int(
134+ UNITYSHELL_LAUNCHER_KEY,
135+ UNITYSHELL_LAUNCHER_MODE,
136+ )
119 self.addCleanup(self._reset_launcher)
137 self.addCleanup(self._reset_launcher)
120
138
121 self._proxy = None
139 self._proxy = None
@@ -136,7 +154,10 @@ class UnityTestCase(AutopilotTestCase):
136
154
137 def _reset_launcher(self):
155 def _reset_launcher(self):
138 """Reset Unity launcher hide mode"""
156 """Reset Unity launcher hide mode"""
139− self._unityshell_schema.set_int(UNITYSHELL_LAUNCHER_KEY, self._launcher_hide_mode)
157+ self._unityshell_schema.set_int(
158+ UNITYSHELL_LAUNCHER_KEY,
159+ self._launcher_hide_mode,
160+ )
140
161
141 def _setup_display_details(self):
162 def _setup_display_details(self):
142 scale_divisor = self._determine_geometry()
163 scale_divisor = self._determine_geometry()
@@ -217,7 +238,10 @@ class UnityTestCase(AutopilotTestCase):
217 def _upstart_reset_env(self, key, value):
238 def _upstart_reset_env(self, key, value):
218 logger.info("Resetting upstart env %s to %s", key, value)
239 logger.info("Resetting upstart env %s to %s", key, value)
219 if value is None:
240 if value is None:
241+ subprocess.call(
220− subprocess.call(["/sbin/initctl", "unset-env", key], stderr=subprocess.STDOUT)
242+ ["/sbin/initctl", "unset-env", key],
243+ stderr=subprocess.STDOUT,
244+ )
221 else:
245 else:
222 subprocess.call([
246 subprocess.call([
223 "/sbin/initctl",
247 "/sbin/initctl",
@@ -244,9 +268,13 @@ class UnityTestCase(AutopilotTestCase):
244 self._setup_extra_mock_environment_patch()
268 self._setup_extra_mock_environment_patch()
245
269
246 # FIXME: we shouldn't be doing this
270 # FIXME: we shouldn't be doing this
247− # $MIR_SOCKET, fallback to $XDG_RUNTIME_DIR/mir_socket and /tmp/mir_socket as last resort
271+ # $MIR_SOCKET, fallback to $XDG_RUNTIME_DIR/mir_socket and
272+ # /tmp/mir_socket as last resort
248 try:
273 try:
274+ os.unlink(
275+ os.getenv('MIR_SOCKET',
249− os.unlink(os.getenv('MIR_SOCKET', os.path.join(os.getenv('XDG_RUNTIME_DIR', "/tmp"), "mir_socket")))
276+ os.path.join(os.getenv('XDG_RUNTIME_DIR', "/tmp"),
277+ "mir_socket")))
250 except OSError:
278 except OSError:
251 pass
279 pass
252 try:
280 try:
@@ -256,7 +284,7 @@ class UnityTestCase(AutopilotTestCase):
256
284
257 app_proxy = self._launch_unity_with_upstart(
285 app_proxy = self._launch_unity_with_upstart(
258 binary_path,
286 binary_path,
259− self.unity_geometry_args
287+ self.unity_geometry_args,
260 )
288 )
261
289
262 self._set_proxy(app_proxy)
290 self._set_proxy(app_proxy)
@@ -274,29 +302,20 @@ class UnityTestCase(AutopilotTestCase):
274
302
275 binary_arg = "BINARY=%s" % binary_path
303 binary_arg = "BINARY=%s" % binary_path
276 extra_args = "ARGS=%s" % " ".join(args)
304 extra_args = "ARGS=%s" % " ".join(args)
277−
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()],
305+ env_args = ["%s=%s" % (k, v) for k, v in self._environment.iteritems()]
285− stderr=subprocess.STDOUT)
306+ all_args = [binary_arg, extra_args] + env_args
286
307
287 self.addCleanup(self._cleanup_launching_upstart_unity)
308 self.addCleanup(self._cleanup_launching_upstart_unity)
288
309
289− pid = int(output.split()[-1])
310+ return restart_unity_with_testability(*all_args)
290−
291− return get_proxy_object_for_existing_process(
292− pid=pid,
293− emulator_base=UnityEmulatorBase,
294− )
295
311
296 def _cleanup_launching_upstart_unity(self):
312 def _cleanup_launching_upstart_unity(self):
297 logger.info("Stopping unity")
313 logger.info("Stopping unity")
298 try:
314 try:
299− subprocess.check_output(["/sbin/initctl", "stop", "unity8"], stderr=subprocess.STDOUT)
315+ subprocess.check_output(
316+ ["/sbin/initctl", "stop", "unity8"],
317+ stderr=subprocess.STDOUT
318+ )
300 except subprocess.CalledProcessError:
319 except subprocess.CalledProcessError:
301 logger.warning("Appears unity was already stopped!")
320 logger.warning("Appears unity was already stopped!")
302
321
@@ -366,8 +385,7 @@ class UnityTestCase(AutopilotTestCase):
366 self.assertThat(home_scope.isCurrent, Eventually(Equals(True)))
385 self.assertThat(home_scope.isCurrent, Eventually(Equals(True)))
367
386
368 def get_dash(self):
387 def get_dash(self):
369− dash = self._proxy.select_single(Dash)
388+ dash = self._proxy.wait_select_single(Dash)
370− self.assertThat(dash, NotEquals(None))
371 return dash
389 return dash
372
390
373 @property
391 @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_hud.py+11−10
@@ -19,6 +19,7 @@
19
19
20from __future__ import absolute_import
20from __future__ import absolute_import
21
21
22+from unity8.process_helpers import unlock_unity
22from unity8.shell import with_lightdm_mock, DragMixin
23from unity8.shell import with_lightdm_mock, DragMixin
23from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
24from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
24
25
@@ -38,8 +39,8 @@ class TestHud(UnityTestCase, DragMixin):
38 The button must disappear when touching somewhere on the screen except the button itself.
39 The button must disappear when touching somewhere on the screen except the button itself.
39
40
40 """
41 """
41− self.launch_unity()
42+ unity_proxy = self.launch_unity()
42− self.main_window.get_greeter().swipe()
43+ unlock_unity(unity_proxy)
43 window = self.main_window.get_qml_view()
44 window = self.main_window.get_qml_view()
44 hud_show_button = self.main_window.get_hud_show_button()
45 hud_show_button = self.main_window.get_hud_show_button()
45 edge_drag_area = self.main_window.get_hud_edge_drag_area()
46 edge_drag_area = self.main_window.get_hud_edge_drag_area()
@@ -80,8 +81,8 @@ class TestHud(UnityTestCase, DragMixin):
80 Test that the hud button stays on screen and tapping it opens the hud.
81 Test that the hud button stays on screen and tapping it opens the hud.
81
82
82 """
83 """
83− self.launch_unity()
84+ unity_proxy = self.launch_unity()
84− self.main_window.get_greeter().swipe()
85+ unlock_unity(unity_proxy)
85 window = self.main_window.get_qml_view()
86 window = self.main_window.get_qml_view()
86 hud_show_button = self.main_window.get_hud_show_button()
87 hud_show_button = self.main_window.get_hud_show_button()
87 hud = self.main_window.get_hud()
88 hud = self.main_window.get_hud()
@@ -117,8 +118,8 @@ class TestHud(UnityTestCase, DragMixin):
117
118
118 def test_hide_hud_click(self):
119 def test_hide_hud_click(self):
119 """Tapping the close button of the Hud must dismiss it."""
120 """Tapping the close button of the Hud must dismiss it."""
120− self.launch_unity()
121+ unity_proxy = self.launch_unity()
121− self.main_window.get_greeter().swipe()
122+ unlock_unity(unity_proxy)
122 hud = self.main_window.get_hud()
123 hud = self.main_window.get_hud()
123
124
124 self._launch_test_app_from_app_screen()
125 self._launch_test_app_from_app_screen()
@@ -134,8 +135,8 @@ class TestHud(UnityTestCase, DragMixin):
134 released downward.
135 released downward.
135
136
136 """
137 """
137− self.launch_unity()
138+ unity_proxy = self.launch_unity()
138− self.main_window.get_greeter().swipe()
139+ unlock_unity(unity_proxy)
139 window = self.main_window.get_qml_view()
140 window = self.main_window.get_qml_view()
140 hud = self.main_window.get_hud()
141 hud = self.main_window.get_hud()
141
142
@@ -152,8 +153,8 @@ class TestHud(UnityTestCase, DragMixin):
152
153
153 def test_launcher_hides_hud(self):
154 def test_launcher_hides_hud(self):
154 """Opening the Launcher while the Hud is active must close the Hud."""
155 """Opening the Launcher while the Hud is active must close the Hud."""
155− self.launch_unity()
156+ unity_proxy = self.launch_unity()
156− self.main_window.get_greeter().swipe()
157+ unlock_unity(unity_proxy)
157 hud = self.main_window.get_hud()
158 hud = self.main_window.get_hud()
158 launcher = self.main_window.get_launcher()
159 launcher = self.main_window.get_launcher()
159
160
tests/autopilot/unity8/shell/tests/test_notifications.py+74−72
@@ -21,6 +21,7 @@
21
21
22from __future__ import absolute_import
22from __future__ import absolute_import
23
23
24+from unity8.process_helpers import unlock_unity
24from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
25from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
25
26
26from testtools.matchers import Equals, NotEquals
27from testtools.matchers import Equals, NotEquals
@@ -45,7 +46,7 @@ class NotificationsBase(UnityTestCase):
45 """Given an icons file name returns the full path (either system or
46 """Given an icons file name returns the full path (either system or
46 source tree.
47 source tree.
47
48
48− Consider the graphics directory as root so for example (runnign tests
49+ Consider the graphics directory as root so for example (running tests
49 from installed unity8-autopilot package):
50 from installed unity8-autopilot package):
50 >>> self.get_icon_path('clock.png')
51 >>> self.get_icon_path('clock.png')
51 /usr/share/unity8/graphics/clock.png
52 /usr/share/unity8/graphics/clock.png
@@ -118,9 +119,8 @@ class InteractiveNotificationBase(NotificationsBase):
118
119
119 def test_interactive(self):
120 def test_interactive(self):
120 """Interactive notification must react upon click on itself."""
121 """Interactive notification must react upon click on itself."""
121− self.launch_unity()
122+ unity_proxy = self.launch_unity()
122− greeter = self.main_window.get_greeter()
123+ unlock_unity(unity_proxy)
123− greeter.swipe()
124
124
125 notify_list = self._get_notifications_list()
125 notify_list = self._get_notifications_list()
126
126
@@ -145,8 +145,8 @@ class InteractiveNotificationBase(NotificationsBase):
145 hints,
145 hints,
146 )
146 )
147
147
148+ get_notification = lambda: notify_list.wait_select_single(
148− get_notification = lambda: notify_list.select_single('Notification', objectName='notification1')
149+ 'Notification', objectName='notification1')
149− self.assertThat(get_notification, Eventually(NotEquals(None)))
150 notification = get_notification()
150 notification = get_notification()
151
151
152 self.touch.tap_object(
152 self.touch.tap_object(
@@ -156,10 +156,10 @@ class InteractiveNotificationBase(NotificationsBase):
156 self.assert_notification_action_id_was_called('action_id')
156 self.assert_notification_action_id_was_called('action_id')
157
157
158 def test_sd_incoming_call(self):
158 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."""
160− self.launch_unity()
161+ unity_proxy = self.launch_unity()
161− greeter = self.main_window.get_greeter()
162+ unlock_unity(unity_proxy)
162− greeter.swipe()
163
163
164 notify_list = self._get_notifications_list()
164 notify_list = self._get_notifications_list()
165
165
@@ -191,8 +191,8 @@ class InteractiveNotificationBase(NotificationsBase):
191 hints
191 hints
192 )
192 )
193
193
194+ get_notification = lambda: notify_list.wait_select_single(
194− get_notification = lambda: notify_list.select_single('Notification', objectName='notification1')
195+ 'Notification', objectName='notification1')
195− self.assertThat(get_notification, Eventually(NotEquals(None)))
196 notification = get_notification()
196 notification = get_notification()
197 self._assert_notification(notification, None, None, True, True, 1.0)
197 self._assert_notification(notification, None, None, True, True, 1.0)
198 initial_height = notification.height
198 initial_height = notification.height
@@ -200,8 +200,10 @@ class InteractiveNotificationBase(NotificationsBase):
200 self.assertThat(
200 self.assertThat(
201 notification.height,
201 notification.height,
202 Eventually(Equals(initial_height +
202 Eventually(Equals(initial_height +
203+ 3 * notification.select_single(
203− 3 * notification.select_single(objectName="buttonColumn").spacing +
204+ objectName="buttonColumn").spacing +
204− 3 * notification.select_single(objectName="button4").height)))
205+ 3 * notification.select_single(
206+ objectName="button4").height)))
205 self.touch.tap_object(notification.select_single(objectName="button4"))
207 self.touch.tap_object(notification.select_single(objectName="button4"))
206 self.assert_notification_action_id_was_called("action_decline_4")
208 self.assert_notification_action_id_was_called("action_decline_4")
207
209
@@ -333,9 +335,8 @@ class EphemeralNotificationsTests(NotificationsBase):
333
335
334 def test_icon_summary_body(self):
336 def test_icon_summary_body(self):
335 """Notification must display the expected summary and body text."""
337 """Notification must display the expected summary and body text."""
336− self.launch_unity()
338+ unity_proxy = self.launch_unity()
337− greeter = self.main_window.get_greeter()
339+ unlock_unity(unity_proxy)
338− greeter.swipe()
339
340
340 notify_list = self._get_notifications_list()
341 notify_list = self._get_notifications_list()
341
342
@@ -360,16 +361,22 @@ class EphemeralNotificationsTests(NotificationsBase):
360
361
361 notification.show()
362 notification.show()
362
363
364+ notification = lambda: notify_list.wait_select_single(
363− get_notification = lambda: notify_list.select_single('Notification', objectName='notification1')
365+ '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+ self._assert_notification(
367+ notification(),
368+ summary,
369+ body,
370+ True,
371+ True,
372+ 1.0,
373+ )
367
374
368 def test_icon_summary(self):
375 def test_icon_summary(self):
369− """Notification must display the expected summary and secondary icon."""
376+ """Notification must display the expected summary and secondary
370− self.launch_unity()
377+ icon."""
371− greeter = self.main_window.get_greeter()
378+ unity_proxy = self.launch_unity()
372− greeter.swipe()
379+ unlock_unity(unity_proxy)
373
380
374 notify_list = self._get_notifications_list()
381 notify_list = self._get_notifications_list()
375
382
@@ -391,11 +398,11 @@ class EphemeralNotificationsTests(NotificationsBase):
391
398
392 notification.show()
399 notification.show()
393
400
401+ notification = lambda: notify_list.wait_select_single(
394− get_notification = lambda: notify_list.select_single('Notification', objectName='notification1')
402+ 'Notification', objectName='notification1')
395− self.assertThat(get_notification, Eventually(NotEquals(None)))
403+
396− notification = get_notification()
397 self._assert_notification(
404 self._assert_notification(
398− notification,
405+ notification(),
399 summary,
406 summary,
400 None,
407 None,
401 False,
408 False,
@@ -404,10 +411,10 @@ class EphemeralNotificationsTests(NotificationsBase):
404 )
411 )
405
412
406 def test_urgency_order(self):
413 def test_urgency_order(self):
407− """Notifications must be displayed in order according to their urgency."""
414+ """Notifications must be displayed in order according to their
408− self.launch_unity()
415+ urgency."""
409− greeter = self.main_window.get_greeter()
416+ unity_proxy = self.launch_unity()
410− greeter.swipe()
417+ unlock_unity(unity_proxy)
411
418
412 notify_list = self._get_notifications_list()
419 notify_list = self._get_notifications_list()
413
420
@@ -448,11 +455,10 @@ class EphemeralNotificationsTests(NotificationsBase):
448 )
455 )
449 notification_critical.show()
456 notification_critical.show()
450
457
451− get_notification = lambda: notify_list.select_single(
458+ get_notification = lambda: notify_list.wait_select_single(
452 'Notification',
459 'Notification',
453 summary=summary_critical
460 summary=summary_critical
454 )
461 )
455− self.assertThat(get_notification, Eventually(NotEquals(None)))
456
462
457 notification = get_notification()
463 notification = get_notification()
458 self._assert_notification(
464 self._assert_notification(
@@ -464,11 +470,10 @@ class EphemeralNotificationsTests(NotificationsBase):
464 1.0
470 1.0
465 )
471 )
466
472
467− get_normal_notification = lambda: notify_list.select_single(
473+ get_normal_notification = lambda: notify_list.wait_select_single(
468 'Notification',
474 'Notification',
469 summary=summary_normal
475 summary=summary_normal
470 )
476 )
471− self.assertThat(get_normal_notification, Eventually(NotEquals(None)))
472 notification = get_normal_notification()
477 notification = get_normal_notification()
473 self._assert_notification(
478 self._assert_notification(
474 notification,
479 notification,
@@ -479,11 +484,10 @@ class EphemeralNotificationsTests(NotificationsBase):
479 1.0
484 1.0
480 )
485 )
481
486
482− get_low_notification = lambda: notify_list.select_single(
487+ get_low_notification = lambda: notify_list.wait_select_single(
483 'Notification',
488 'Notification',
484 summary=summary_low
489 summary=summary_low
485 )
490 )
486− self.assertThat(get_low_notification, Eventually(NotEquals(None)))
487 notification = get_low_notification()
491 notification = get_low_notification()
488 self._assert_notification(
492 self._assert_notification(
489 notification,
493 notification,
@@ -496,9 +500,8 @@ class EphemeralNotificationsTests(NotificationsBase):
496
500
497 def test_summary_and_body(self):
501 def test_summary_and_body(self):
498 """Notification must display the expected summary- and body-text."""
502 """Notification must display the expected summary- and body-text."""
499− self.launch_unity()
503+ unity_proxy = self.launch_unity()
500− greeter = self.main_window.get_greeter()
504+ unlock_unity(unity_proxy)
501− greeter.swipe()
502
505
503 notify_list = self._get_notifications_list()
506 notify_list = self._get_notifications_list()
504
507
@@ -508,9 +511,9 @@ class EphemeralNotificationsTests(NotificationsBase):
508 notification = self._create_ephemeral_notification(summary, body)
511 notification = self._create_ephemeral_notification(summary, body)
509 notification.show()
512 notification.show()
510
513
514+ notification = notify_list.wait_select_single(
511− get_notification = lambda: notify_list.select_single('Notification', objectName='notification1')
515+ 'Notification', objectName='notification1')
512− self.assertThat(get_notification, Eventually(NotEquals(None)))
516+
513− notification = get_notification()
514 self._assert_notification(
517 self._assert_notification(
515 notification,
518 notification,
516 summary,
519 summary,
@@ -522,9 +525,8 @@ class EphemeralNotificationsTests(NotificationsBase):
522
525
523 def test_summary_only(self):
526 def test_summary_only(self):
524 """Notification must display only the expected summary-text."""
527 """Notification must display only the expected summary-text."""
525− self.launch_unity()
528+ unity_proxy = self.launch_unity()
526− greeter = self.main_window.get_greeter()
529+ unlock_unity(unity_proxy)
527− greeter.swipe()
528
530
529 notify_list = self._get_notifications_list()
531 notify_list = self._get_notifications_list()
530
532
@@ -533,17 +535,16 @@ class EphemeralNotificationsTests(NotificationsBase):
533 notification = self._create_ephemeral_notification(summary)
535 notification = self._create_ephemeral_notification(summary)
534 notification.show()
536 notification.show()
535
537
538+ notification = notify_list.wait_select_single(
536− get_notification = lambda: notify_list.select_single('Notification', objectName='notification1')
539+ 'Notification', objectName='notification1')
537− self.assertThat(get_notification, Eventually(NotEquals(None)))
538− notification = get_notification()
539
540
540 self._assert_notification(notification, summary, '', False, False, 1.0)
541 self._assert_notification(notification, summary, '', False, False, 1.0)
541
542
542 def test_update_notification_same_layout(self):
543 def test_update_notification_same_layout(self):
543− """Notification must allow updating its contents while being displayed."""
544+ """Notification must allow updating its contents while being
544− self.launch_unity()
545+ displayed."""
545− greeter = self.main_window.get_greeter()
546+ unity_proxy = self.launch_unity()
546− greeter.swipe()
547+ unlock_unity(unity_proxy)
547
548
548 notify_list = self._get_notifications_list()
549 notify_list = self._get_notifications_list()
549
550
@@ -558,8 +559,8 @@ class EphemeralNotificationsTests(NotificationsBase):
558 )
559 )
559 notification.show()
560 notification.show()
560
561
561− get_notification = lambda: notify_list.select_single('Notification', summary=summary)
562+ get_notification = lambda: notify_list.wait_select_single(
562− self.assertThat(get_notification, Eventually(NotEquals(None)))
563+ 'Notification', summary=summary)
563 self._assert_notification(
564 self._assert_notification(
564 get_notification(),
565 get_notification(),
565 summary,
566 summary,
@@ -575,14 +576,13 @@ class EphemeralNotificationsTests(NotificationsBase):
575 icon_path = self._get_icon_path('avatars/amanda.png')
576 icon_path = self._get_icon_path('avatars/amanda.png')
576 notification.update(summary, body, icon_path)
577 notification.update(summary, body, icon_path)
577 notification.show()
578 notification.show()
578− self.assertThat(get_notification, Eventually(NotEquals(None)))
579 self._assert_notification(get_notification(), summary, body)
579 self._assert_notification(get_notification(), summary, body)
580
580
581 def test_update_notification_layout_change(self):
581 def test_update_notification_layout_change(self):
582− """Notification must allow updating its contents and layout while being displayed."""
582+ """Notification must allow updating its contents and layout while
583− self.launch_unity()
583+ being displayed."""
584− greeter = self.main_window.get_greeter()
584+ unity_proxy = self.launch_unity()
585− greeter.swipe()
585+ unlock_unity(unity_proxy)
586
586
587 notify_list = self._get_notifications_list()
587 notify_list = self._get_notifications_list()
588
588
@@ -603,8 +603,9 @@ class EphemeralNotificationsTests(NotificationsBase):
603 )
603 )
604 notification.show()
604 notification.show()
605
605
606+ get_notification = lambda: notify_list.wait_select_single(
606− get_notification = lambda: notify_list.select_single('Notification', objectName='notification1')
607+ 'Notification', objectName='notification1')
607− self.assertThat(get_notification, Eventually(NotEquals(None)))
608+
608 self._assert_notification(
609 self._assert_notification(
609 get_notification(),
610 get_notification(),
610 summary,
611 summary,
@@ -626,9 +627,8 @@ class EphemeralNotificationsTests(NotificationsBase):
626
627
627 def test_append_hint(self):
628 def test_append_hint(self):
628 """Notification has to accumulate body-text using append-hint."""
629 """Notification has to accumulate body-text using append-hint."""
629− self.launch_unity()
630+ unity_proxy = self.launch_unity()
630− greeter = self.main_window.get_greeter()
631+ unlock_unity(unity_proxy)
631− greeter.swipe()
632
632
633 notify_list = self._get_notifications_list()
633 notify_list = self._get_notifications_list()
634
634
@@ -645,8 +645,9 @@ class EphemeralNotificationsTests(NotificationsBase):
645
645
646 notification.show()
646 notification.show()
647
647
648+ get_notification = lambda: notify_list.wait_select_single(
648− get_notification = lambda: notify_list.select_single('Notification', objectName='notification1')
649+ 'Notification', objectName='notification1')
649− self.assertThat(get_notification, Eventually(NotEquals(None)))
650+
650 notification = get_notification()
651 notification = get_notification()
651 self._assert_notification(
652 self._assert_notification(
652 notification,
653 notification,
@@ -662,7 +663,8 @@ class EphemeralNotificationsTests(NotificationsBase):
662 'Did you watch the air-race in Oshkosh last week?',
663 'Did you watch the air-race in Oshkosh last week?',
663 'Phil owned the place like no one before him!',
664 'Phil owned the place like no one before him!',
664 'Did really everything in the race work according to regulations?',
665 '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.',
666+ 'Somehow I think to remember Burt Williams did cut corners and '
667+ 'was not punished for this.',
666 'Hopefully the referees will watch the videos of the race.',
668 'Hopefully the referees will watch the videos of the race.',
667 'Burt could get fined with US$ 50000 for that rule-violation :)'
669 'Burt could get fined with US$ 50000 for that rule-violation :)'
668 ]
670 ]
@@ -677,11 +679,11 @@ class EphemeralNotificationsTests(NotificationsBase):
677 hints=[('x-canonical-append', 'true')]
679 hints=[('x-canonical-append', 'true')]
678 )
680 )
679 notification.show()
681 notification.show()
682+
680− get_notification = lambda: notify_list.select_single(
683+ get_notification = lambda: notify_list.wait_select_single(
681 'Notification',
684 'Notification',
682 objectName='notification1'
685 objectName='notification1'
683 )
686 )
684− self.assertThat(get_notification, Eventually(NotEquals(None)))
685 notification = get_notification()
687 notification = get_notification()
686 self._assert_notification(
688 self._assert_notification(
687 notification,
689 notification,
tests/mocks/AccountsService/CMakeLists.txt+2−2
@@ -13,9 +13,9 @@ file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
13 )
13 )
14
14
15install(TARGETS MockAccountsService-qml
15install(TARGETS MockAccountsService-qml
16− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/AccountsService
16+ DESTINATION ${SHELL_INSTALL_QML}/mocks/AccountsService
17 )
17 )
18
18
19install(FILES qmldir
19install(FILES qmldir
20− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/AccountsService
20+ DESTINATION ${SHELL_INSTALL_QML}/mocks/AccountsService
21 )
21 )
tests/mocks/AccountsService/plugin.cpp+1−1
@@ -20,7 +20,7 @@
20#include "plugin.h"
20#include "plugin.h"
21#include "AccountsService.h"
21#include "AccountsService.h"
22
22
23−#include <QtQml>
23+#include <QtQml/qqml.h>
24
24
25static QObject *service_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
25static QObject *service_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
26{
26{
tests/mocks/LightDM/CMakeLists.txt+2−2
@@ -47,9 +47,9 @@ file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
47 )
47 )
48
48
49install(TARGETS MockLightDM-qml
49install(TARGETS MockLightDM-qml
50− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/LightDM
50+ DESTINATION ${SHELL_INSTALL_QML}/mocks/LightDM
51 )
51 )
52
52
53install(FILES qmldir
53install(FILES qmldir
54− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/LightDM
54+ DESTINATION ${SHELL_INSTALL_QML}/mocks/LightDM
55 )
55 )
tests/mocks/LightDM/full/CMakeLists.txt+1−1
@@ -14,5 +14,5 @@ set_target_properties(MockLightDM-full PROPERTIES
14 OUTPUT_NAME lightdm-qt5-2)
14 OUTPUT_NAME lightdm-qt5-2)
15
15
16install(TARGETS MockLightDM-full
16install(TARGETS MockLightDM-full
17− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/LightDM/full
17+ DESTINATION ${SHELL_INSTALL_QML}/mocks/LightDM/full
18 )
18 )
tests/mocks/LightDM/single-passphrase/CMakeLists.txt+1−1
@@ -15,5 +15,5 @@ set_target_properties(MockLightDM-single-passphrase PROPERTIES
15 OUTPUT_NAME lightdm-qt5-2)
15 OUTPUT_NAME lightdm-qt5-2)
16
16
17install(TARGETS MockLightDM-single-passphrase
17install(TARGETS MockLightDM-single-passphrase
18− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/LightDM/single-passphrase
18+ DESTINATION ${SHELL_INSTALL_QML}/mocks/LightDM/single-passphrase
19 )
19 )
tests/mocks/LightDM/single-pin/CMakeLists.txt+1−1
@@ -15,5 +15,5 @@ set_target_properties(MockLightDM-single-pin PROPERTIES
15 OUTPUT_NAME lightdm-qt5-2)
15 OUTPUT_NAME lightdm-qt5-2)
16
16
17install(TARGETS MockLightDM-single-pin
17install(TARGETS MockLightDM-single-pin
18− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/LightDM/single-pin
18+ DESTINATION ${SHELL_INSTALL_QML}/mocks/LightDM/single-pin
19 )
19 )
tests/mocks/LightDM/single/CMakeLists.txt+1−1
@@ -14,5 +14,5 @@ set_target_properties(MockLightDM-single PROPERTIES
14 OUTPUT_NAME lightdm-qt5-2)
14 OUTPUT_NAME lightdm-qt5-2)
15
15
16install(TARGETS MockLightDM-single
16install(TARGETS MockLightDM-single
17− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/LightDM/single
17+ DESTINATION ${SHELL_INSTALL_QML}/mocks/LightDM/single
18 )
18 )
tests/mocks/Powerd/CMakeLists.txt+2−2
@@ -13,9 +13,9 @@ file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
13 )
13 )
14
14
15install(TARGETS MockPowerd-qml
15install(TARGETS MockPowerd-qml
16− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/Powerd
16+ DESTINATION ${SHELL_INSTALL_QML}/mocks/Powerd
17 )
17 )
18
18
19install(FILES qmldir
19install(FILES qmldir
20− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/Powerd
20+ DESTINATION ${SHELL_INSTALL_QML}/mocks/Powerd
21 )
21 )
tests/mocks/QMenuModel/CMakeLists.txt+23
@@ -9,3 +9,26 @@ add_custom_target(QMenuModelQmlFiles ALL
9 COMMAND cp ${QMLFILES} ${CMAKE_CURRENT_BINARY_DIR}
9 COMMAND cp ${QMLFILES} ${CMAKE_CURRENT_BINARY_DIR}
10 DEPENDS ${QMLFILES}
10 DEPENDS ${QMLFILES}
11)
11)
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)
plugins/Unity/genericpreview.cpp → tests/mocks/QMenuModel/UnityMenuAction.qmlrenamed+11−12
@@ -1,9 +1,6 @@
1/*
1/*
2 * Copyright (C) 2013 Canonical, Ltd.
2 * Copyright (C) 2013 Canonical, Ltd.
3 *
3 *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 3.
6 * the Free Software Foundation; version 3.
@@ -15,17 +12,19 @@
15 *
12 *
16 * You should have received a copy of the GNU General Public License
13 * 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/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18 */
18 */
19
19
20−// local
20+import QtQuick 2.0
21−#include "genericpreview.h"
21+import QMenuModel 0.1
22
22
23−GenericPreview::GenericPreview(QObject *parent):
23+QtObject {
24− Preview(parent)
24+ property string name
25−{
25+ property UnityMenuModel model
26−}
26+ property int index
27
27
28−void GenericPreview::setUnityPreview(unity::dash::Preview::Ptr /* unityPreview */)
28+ readonly property var state: undefined
29−{
29+ readonly property bool valid: false
30− Q_EMIT previewChanged();
31}
30}
tests/plugins/Unity/signalslisttest.h → tests/mocks/QMenuModel/actionstateparser.cpprenamed+3−14
@@ -12,19 +12,8 @@
12 *
12 *
13 * You should have received a copy of the GNU General Public License
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/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors: Nick Dedekind <nick.dedekind@canonical.com>
15 */
17 */
16
18
17−#ifndef SIGNALSLISTTEST_H
19+#include "actionstateparser.h"
18−#define SIGNALSLISTTEST_H
19−
20−#include <QObject>
21−
22−class SignalsListTest : public QObject
23−{
24− Q_OBJECT
25−
26− private Q_SLOTS:
27− void testSignalsList();
28−};
29−
30−#endif // SIGNALSLISTTEST_H
tests/plugins/Unity/resultstest.h → tests/mocks/QMenuModel/actionstateparser.hrenamed+11−15
@@ -13,27 +13,23 @@
13 * You should have received a copy of the GNU General Public License
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/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
15 *
16− * Authors:
16+ * Authors: Nick Dedekind <nick.dedekind@canonical.com>
17− * Michal Hruby <michal.hruby@canonical.com>
18 */
17 */
19
18
20−#ifndef RESULTSTEST_H
19+#ifndef MOCK_ACTIONSTATEPARSER_H
21−#define RESULTSTEST_H
20+#define MOCK_ACTIONSTATEPARSER_H
22
21
23#include <QObject>
22#include <QObject>
23+#include <QVariant>
24
24
25+typedef struct _GVariant GVariant;
26+
25−class ResultsTest : public QObject
27+class Q_DECL_EXPORT ActionStateParser : public QObject
26{
28{
27 Q_OBJECT
29 Q_OBJECT
28−
30+public:
29− private Q_SLOTS:
31+ ActionStateParser(QObject* parent = 0):QObject(parent) {}
30− void testAllColumns();
32+ virtual QVariant toQVariant(GVariant*) const { return QVariant(); }
31− void testIconColumn_data();
32− void testIconColumn();
33− void testSpecialIcons_data();
34− void testSpecialIcons();
35− void testMetadataOverride_data();
36− void testMetadataOverride();
37};
33};
38
34
39−#endif
35+#endif // MOCK_ACTIONSTATEPARSER_H
plugins/Unity/ratingoptionsmodel.h → tests/mocks/QMenuModel/plugin.cpprenamed+12−15
@@ -1,8 +1,5 @@
1/*
1/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2012,2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6 *
3 *
7 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -15,19 +12,19 @@
15 *
12 *
16 * You should have received a copy of the GNU General Public License
13 * 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/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors: Nick Dedekind <nick.dedekind@canonical.com>
18 */
17 */
19
18
20−#ifndef RATINGOPTIONSMODEL_H
19+#include "plugin.h"
21−#define RATINGOPTIONSMODEL_H
20+#include "unitymenumodel.h"
21+#include "actionstateparser.h"
22
22
23−#include "genericoptionsmodel.h"
23+#include <QtQml/qqml.h>
24
24
25−class RatingOptionsModel : public GenericOptionsModel
25+void QMenuModelPlugin::registerTypes(const char *uri)
26{
26{
27− Q_OBJECT
27+ Q_ASSERT(uri == QLatin1String("QMenuModel"));
28−
28+ qmlRegisterType<UnityMenuModel>(uri, 0, 1, "UnityMenuModel");
29−public:
29+ qmlRegisterType<ActionStateParser>(uri, 0, 1, "ActionStateParser");
30− RatingOptionsModel(bool showAllOption, QObject *parent);
31−};
30+}
32−
33−#endif // RATINGOPTIONSMODEL_H
plugins/Unity/plugin.h → tests/mocks/QMenuModel/plugin.hrenamed+7−8
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2012 Canonical, Ltd.
2+ * Copyright (C) 2012,2013 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
@@ -13,23 +13,22 @@
13 * You should have received a copy of the GNU General Public License
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/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
15 *
16− * Author: Michał Sawicz <michal.sawicz@canonical.com>
16+ * Authors: Nick Dedekind <nick.dedekind@canonical.com>
17 */
17 */
18
18
19−#ifndef UNITY_PLUGIN_H
19+#ifndef MOCK_QMENUMODEL_PLUGIN_H
20−#define UNITY_PLUGIN_H
20+#define MOCK_QMENUMODEL_PLUGIN_H
21
21
22−#include <QtQml/QQmlEngine>
22+#include <QQmlEngine>
23−#include <QtQml/QQmlExtensionPlugin>
23+#include <QQmlExtensionPlugin>
24
24
25−class UnityPlugin : public QQmlExtensionPlugin
25+class QMenuModelPlugin : public QQmlExtensionPlugin
26{
26{
27 Q_OBJECT
27 Q_OBJECT
28 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
28 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
29
29
30public:
30public:
31 void registerTypes(const char *uri);
31 void registerTypes(const char *uri);
32− void initializeEngine(QQmlEngine *engine, const char *uri);
33};
32};
34
33
35#endif
34#endif
tests/mocks/QMenuModel/qmldir+3−1
@@ -1,3 +1,5 @@
1module QMenuModel
1module QMenuModel
2+plugin qmenumodel
3+
2QDBusActionGroup 0.1 QDBusActionGroup.qml
4QDBusActionGroup 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/Ubuntu/DownloadDaemonListener/CMakeLists.txt+1−1
@@ -14,5 +14,5 @@ add_custom_target(UbuntuDownloadQmlDirFile ALL
14)
14)
15
15
16install(TARGETS FakeUbuntuDownloadDaemonListenerQml
16install(TARGETS FakeUbuntuDownloadDaemonListenerQml
17− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/Ubuntu/DownloadDaemonListener
17+ DESTINATION ${SHELL_INSTALL_QML}/mocks/Ubuntu/DownloadDaemonListener
18 )
18 )
tests/mocks/Unity/Application/CMakeLists.txt+2−2
@@ -29,9 +29,9 @@ add_custom_target(OSKControllerQmlFile ALL
29)
29)
30
30
31install(TARGETS FakeUnityApplicationQml
31install(TARGETS FakeUnityApplicationQml
32− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/Unity/Application
32+ DESTINATION ${SHELL_INSTALL_QML}/mocks/Unity/Application
33 )
33 )
34
34
35install(FILES qmldir InputFilterArea.qml OSKController.qml
35install(FILES qmldir InputFilterArea.qml OSKController.qml
36− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/Unity/Application
36+ DESTINATION ${SHELL_INSTALL_QML}/mocks/Unity/Application
37 )
37 )
tests/mocks/Unity/CMakeLists.txt+2−3
@@ -6,7 +6,6 @@ pkg_search_module(GOBJECT gobject-2.0 REQUIRED)
6pkg_search_module(DEEQT libdee-qt5 REQUIRED)
6pkg_search_module(DEEQT libdee-qt5 REQUIRED)
7
7
8include_directories(
8include_directories(
9− ${CMAKE_SOURCE_DIR}/plugins/Unity
10 ${CMAKE_CURRENT_BINARY_DIR}
9 ${CMAKE_CURRENT_BINARY_DIR}
11 ${Qt5Core_INCLUDE_DIRS}
10 ${Qt5Core_INCLUDE_DIRS}
12 ${Qt5Quick_INCLUDE_DIRS}
11 ${Qt5Quick_INCLUDE_DIRS}
@@ -17,8 +16,8 @@ include_directories(
17add_definitions(-DQT_NO_KEYWORDS)
16add_definitions(-DQT_NO_KEYWORDS)
18
17
19set(UnityQML_SOURCES
18set(UnityQML_SOURCES
20− ${CMAKE_SOURCE_DIR}/plugins/Unity/categoryresults.cpp
19+ categoryresults.cpp
21− ${CMAKE_SOURCE_DIR}/plugins/Unity/iconutils.cpp
20+ iconutils.cpp
22 fake_applications_scope.cpp
21 fake_applications_scope.cpp
23 fake_preview.cpp
22 fake_preview.cpp
24 fake_scope.cpp
23 fake_scope.cpp
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 @@
20import QtQuick 2.0
20import QtQuick 2.0
21
21
22QtObject {
22QtObject {
23− property var menu
23+ property var menu
24− property bool valid: false
24+ property bool valid: false
25− property string title
25+ property string title
26− property string leftLabel
26+ property string leftLabel
27− property string rightLabel
27+ property string rightLabel
28− property var icons
28+ property var icons
29− property string accessibleName
29+ property string accessibleName
30− property bool visible: true
30+ property bool visible: true
31
31
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()
33}
41}
tests/mocks/Unity/Indicators/qmldir+2
@@ -2,6 +2,8 @@ module Unity.Indicators
2plugin IndicatorsFakeQml
2plugin IndicatorsFakeQml
3
3
4CachedUnityMenuModel 0.1 CachedUnityMenuModel.qml
4CachedUnityMenuModel 0.1 CachedUnityMenuModel.qml
5+IndicatorBase 0.1 IndicatorBase.qml
6+IndicatorWidget 0.1 IndicatorWidget.qml
5IndicatorsModel 0.1 IndicatorsModel.qml
7IndicatorsModel 0.1 IndicatorsModel.qml
6FakeMenuPage 0.1 FakeMenuPage.qml
8FakeMenuPage 0.1 FakeMenuPage.qml
7RootActionState 0.1 RootActionState.qml
9RootActionState 0.1 RootActionState.qml
plugins/Unity/categoryresults.cpp → tests/mocks/Unity/categoryresults.cpprenamed

The content is the same.

plugins/Unity/categoryresults.h → tests/mocks/Unity/categoryresults.hrenamed

The content is the same.

tests/mocks/Unity/fake_scope.cpp+3−20
@@ -25,25 +25,8 @@ static DeeModel* create_results_model(unsigned category_count, unsigned result_c
25
25
26// TODO: Implement remaining pieces
26// TODO: Implement remaining pieces
27
27
28−Scope::Scope(QObject* parent)
28+Scope::Scope(QObject* parent) : Scope(QString(), QString(), false, 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))
35{
29{
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− });
47}
30}
48
31
49Scope::Scope(QString const& id, QString const& name, bool visible, QObject* parent)
32Scope::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
56 , m_categories(new Categories(this))
39 , m_categories(new Categories(this))
57 , m_results(new DeeListModel(this))
40 , m_results(new DeeListModel(this))
58{
41{
59− DeeModel* results_model = create_results_model(4, 30);
42+ DeeModel* results_model = create_results_model(20, 300);
60 m_categories->setResultModel(results_model);
43 m_categories->setResultModel(results_model);
61− m_categories->setModel(create_categories_model(4));
44+ m_categories->setModel(create_categories_model(20));
62 m_results->setModel(results_model);
45 m_results->setModel(results_model);
63
46
64 m_timer.setInterval(1000);
47 m_timer.setInterval(1000);
plugins/Unity/iconutils.cpp → tests/mocks/Unity/iconutils.cpprenamed+10−10
@@ -17,11 +17,13 @@
17 * Michal Hruby <michal.hruby@canonical.com>
17 * Michal Hruby <michal.hruby@canonical.com>
18 */
18 */
19
19
20−#include <QStringList>
20+#include "iconutils.h"
21−#include <QUrl>
22
21
23#include <gio/gio.h>
22#include <gio/gio.h>
23+
24−#include "iconutils.h"
24+#include <QStringList>
25+#include <QUrl>
26+#include <QUrlQuery>
25
27
26#define BASE_THEME_ICON_URI "image://theme/"
28#define BASE_THEME_ICON_URI "image://theme/"
27#define BASE_THUMBNAILER_URI "image://thumbnailer/"
29#define BASE_THUMBNAILER_URI "image://thumbnailer/"
@@ -104,13 +106,11 @@ QString uriToThumbnailerProviderString(QString const &uri, QString const &mimety
104 if (contentHash.contains("content")) { // nested content in Home?
106 if (contentHash.contains("content")) { // nested content in Home?
105 contentHash = contentHash["content"].toHash();
107 contentHash = contentHash["content"].toHash();
106 }
108 }
107− if (contentHash.contains("album") &&
109+ if (contentHash.contains("album") && contentHash.contains("artist")) {
108− contentHash.contains("artist")) {
110+ QUrlQuery query;
109− const QString album = contentHash["album"].toString();
111+ query.addQueryItem(QStringLiteral("artist"), contentHash["artist"].toString());
110− const QString artist = contentHash["artist"].toString();
112+ query.addQueryItem(QStringLiteral("album"), contentHash["album"].toString());
111− thumbnailerUri.append(QUrl::toPercentEncoding(artist));
112− thumbnailerUri.append("/");
113+ thumbnailerUri.append(query.toString());
113− thumbnailerUri.append(QUrl::toPercentEncoding(album));
114 }
114 }
115 }
115 }
116 } else {
116 } else {
plugins/Unity/iconutils.h → tests/mocks/Unity/iconutils.hrenamed

The content is the same.

tests/mocks/libusermetrics/CMakeLists.txt+1−1
@@ -13,5 +13,5 @@ set_target_properties(MockUserMetrics PROPERTIES
13 VERSION 1)
13 VERSION 1)
14
14
15install(TARGETS MockUserMetrics
15install(TARGETS MockUserMetrics
16− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/libusermetrics
16+ DESTINATION ${SHELL_INSTALL_QML}/mocks/libusermetrics
17 )
17 )
tests/plugins/ListViewWithPageHeader/CMakeLists.txt+7
@@ -1,3 +1,6 @@
1+# add_qml_test macro
2+include(QmlTest)
3+
1# There's no cmake var for v8 include path :-/
4# There's no cmake var for v8 include path :-/
2# so create one
5# so create one
3LIST(GET Qt5Core_INCLUDE_DIRS 0 QtCoreDir0)
6LIST(GET Qt5Core_INCLUDE_DIRS 0 QtCoreDir0)
@@ -37,6 +40,10 @@ qt5_use_modules(listviewwithpageheadertestsectionexternalmodelExec Test Core Qml
37target_link_libraries(listviewwithpageheadertestsectionexternalmodelExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
40target_link_libraries(listviewwithpageheadertestsectionexternalmodelExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
38add_custom_target(testlistviewwithpageheadersectionexternalmodel ${CMAKE_CURRENT_BINARY_DIR}/listviewwithpageheadertestsectionexternalmodelExec -o ${CMAKE_BINARY_DIR}/testlistviewwithpageheadersectionexternalmodel.xml,xunitxml -o -,txt)
41add_custom_target(testlistviewwithpageheadersectionexternalmodel ${CMAKE_CURRENT_BINARY_DIR}/listviewwithpageheadertestsectionexternalmodelExec -o ${CMAKE_BINARY_DIR}/testlistviewwithpageheadersectionexternalmodel.xml,xunitxml -o -,txt)
39
42
43+set(qmltest_DEFAULT_NO_ADD_TEST TRUE)
44+add_qml_test(. listviewwithpageheaderqml IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
45+
40add_dependencies(qmluitests testlistviewwithpageheader)
46add_dependencies(qmluitests testlistviewwithpageheader)
41add_dependencies(qmluitests testlistviewwithpageheadersection)
47add_dependencies(qmluitests testlistviewwithpageheadersection)
42add_dependencies(qmluitests testlistviewwithpageheadersectionexternalmodel)
48add_dependencies(qmluitests testlistviewwithpageheadersectionexternalmodel)
49+add_dependencies(qmluitests testlistviewwithpageheaderqml)
tests/plugins/ListViewWithPageHeader/listviewwithpageheadertest.cpp+42
@@ -1589,6 +1589,28 @@ private Q_SLOTS:
1589 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1589 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1590 }
1590 }
1591
1591
1592+ void testMaximizeVisibleAreaTopWithHalfPageHeaderUpDown()
1593+ {
1594+ testMaximizeVisibleAreaTopWithHalfPageHeader();
1595+
1596+ changeContentY(-60);
1597+ changeContentY(15);
1598+
1599+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
1600+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1601+ verifyItem(0, -140., 150., false);
1602+ verifyItem(1, 10., 200., false);
1603+ verifyItem(2, 210, 350., false);
1604+ verifyItem(3, 560, 350., true);
1605+ QCOMPARE(lvwph->m_minYExtent, 0.);
1606+ QCOMPARE(lvwph->m_clipItem->y(), 190.);
1607+ QCOMPARE(lvwph->m_clipItem->clip(), true);
1608+ QCOMPARE(lvwph->m_headerItem->y(), 140.);
1609+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1610+ QCOMPARE(lvwph->contentY(), 155.);
1611+ QCOMPARE(lvwph->m_headerItemShownHeight, 35.);
1612+ }
1613+
1592 void testMaximizeVisibleAreaBottomWithHalfPageHeader()
1614 void testMaximizeVisibleAreaBottomWithHalfPageHeader()
1593 {
1615 {
1594 changeContentY(430);
1616 changeContentY(430);
@@ -1724,6 +1746,9 @@ private Q_SLOTS:
1724
1746
1725 void testMaximizeVisibleAreaMoveUpAndShowHeader()
1747 void testMaximizeVisibleAreaMoveUpAndShowHeader()
1726 {
1748 {
1749+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
1750+ QSKIP("This test is extremely unstable in 5.0.x");
1751+#endif
1727 model->setProperty(0, "size", 800);
1752 model->setProperty(0, "size", 800);
1728 verifyItem(0, 50., 800., false);
1753 verifyItem(0, 50., 800., false);
1729
1754
@@ -1824,6 +1849,23 @@ private Q_SLOTS:
1824 lvwph->positionAtBeginning();
1849 lvwph->positionAtBeginning();
1825 }
1850 }
1826
1851
1852+ void testHeaderPositionBug1240118()
1853+ {
1854+ scrollToBottom();
1855+ lvwph->showHeader();
1856+ QTRY_VERIFY(!lvwph->m_contentYAnimation->isRunning());
1857+ QTest::qWait(100); // Make sure stuff is stable
1858+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 100));
1859+ model->setProperty(3, "size", 10);
1860+ model->setProperty(4, "size", 10);
1861+ model->setProperty(5, "size", 10);
1862+ model->setProperty(6, "size", 10);
1863+#if (QT_VERSION > QT_VERSION_CHECK(5, 0, 3))
1864+ QTRY_COMPARE(lvwph->m_minYExtent, 210.);
1865+#endif
1866+ QTRY_COMPARE(lvwph->m_headerItem->y(), -lvwph->m_minYExtent);
1867+ }
1868+
1827private:
1869private:
1828 QQuickView *view;
1870 QQuickView *view;
1829 ListViewWithPageHeader *lvwph;
1871 ListViewWithPageHeader *lvwph;
tests/plugins/ListViewWithPageHeader/listviewwithpageheadertestsection.cpp+81−1
@@ -1734,7 +1734,25 @@ private Q_SLOTS:
1734 QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive"));
1734 QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive"));
1735 QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive"));
1735 QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive"));
1736
1736
1737− changeContentY(140);
1737+ changeContentY(5);
1738+
1739+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 5);
1740+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1741+ verifyItem(0, 45., 90., false, "Agressive", false);
1742+ verifyItem(1, 135., 50., false, QString(), false);
1743+ verifyItem(2, 185., 150., false, QString(), false);
1744+ verifyItem(3, 335., 240., false, "Regular", false);
1745+ verifyItem(4, 575., 390., true, "Mild", true);
1746+ QCOMPARE(lvwph->m_minYExtent, 0.);
1747+ QCOMPARE(lvwph->m_clipItem->y(), 5.);
1748+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1749+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1750+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1751+ QCOMPARE(lvwph->contentY(), 5.);
1752+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1753+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1754+
1755+ changeContentY(135);
1738
1756
1739 QTRY_COMPARE(lvwph->m_visibleItems.count(), 5);
1757 QTRY_COMPARE(lvwph->m_visibleItems.count(), 5);
1740 QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1758 QCOMPARE(lvwph->m_firstVisibleIndex, 0);
@@ -2076,6 +2094,68 @@ private Q_SLOTS:
2076 QCOMPARE(spy.count(), 0);
2094 QCOMPARE(spy.count(), 0);
2077 }
2095 }
2078
2096
2097+ void testDownAndUp()
2098+ {
2099+ QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 1), Q_ARG(QVariant, 5));
2100+
2101+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 1);
2102+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
2103+ verifyItem(0, 50., 190., false, "Agressive", false);
2104+ QCOMPARE(lvwph->m_minYExtent, 0.);
2105+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
2106+ QCOMPARE(lvwph->m_clipItem->clip(), false);
2107+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
2108+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
2109+ QCOMPARE(lvwph->contentY(), 0.);
2110+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
2111+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
2112+
2113+ QTest::qWait(1);
2114+
2115+ changeContentY(-15);
2116+
2117+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 1);
2118+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
2119+ verifyItem(0, 65., 190., false, "Agressive", false);
2120+ QCOMPARE(lvwph->m_minYExtent, 0.);
2121+ QCOMPARE(lvwph->m_clipItem->y(), -15.);
2122+ QCOMPARE(lvwph->m_clipItem->clip(), false);
2123+ QCOMPARE(lvwph->m_headerItem->y(), -15.);
2124+ QCOMPARE(lvwph->m_headerItem->height(), 65.);
2125+ QCOMPARE(lvwph->contentY(), -15.);
2126+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
2127+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
2128+
2129+ changeContentY(25);
2130+
2131+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 1);
2132+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
2133+ verifyItem(0, 40., 190., false, "Agressive", false);
2134+ QCOMPARE(lvwph->m_minYExtent, 0.);
2135+ QCOMPARE(lvwph->m_clipItem->y(), 10.);
2136+ QCOMPARE(lvwph->m_clipItem->clip(), false);
2137+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
2138+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
2139+ QCOMPARE(lvwph->contentY(), 10.);
2140+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
2141+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
2142+
2143+
2144+ QTest::mouseClick(view, Qt::LeftButton, Qt::NoModifier, QPoint(0, 0));
2145+
2146+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 1);
2147+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
2148+ verifyItem(0, 50., 190., false, "Agressive", false);
2149+ QCOMPARE(lvwph->m_minYExtent, 0.);
2150+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
2151+ QCOMPARE(lvwph->m_clipItem->clip(), false);
2152+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
2153+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
2154+ QCOMPARE(lvwph->contentY(), 0.);
2155+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
2156+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
2157+ }
2158+
2079private:
2159private:
2080 QQuickView *view;
2160 QQuickView *view;
2081 ListViewWithPageHeader *lvwph;
2161 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/CMakeLists.txt+20−18
@@ -1,33 +1,34 @@
1−########## tst_DirectionalDragArea
1+include(QmlTest)
2
2
3include_directories(
3include_directories(
4 ${CMAKE_SOURCE_DIR}/plugins/Ubuntu/Gestures
4 ${CMAKE_SOURCE_DIR}/plugins/Ubuntu/Gestures
5 ${CMAKE_CURRENT_BINARY_DIR}
5 ${CMAKE_CURRENT_BINARY_DIR}
6 )
6 )
7
7
8−set(testCommand
9− LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/plugins/Ubuntu/Gestures
10− ${CMAKE_CURRENT_BINARY_DIR}/DirectionalDragAreaTestExec
11− -o ${CMAKE_BINARY_DIR}/DirectionalDragAreaTest.xml,xunitxml
12− -o -,txt)
13−
14−add_custom_target(testDirectionalDragArea ${testCommand})
15−add_dependencies(qmluitests testDirectionalDragArea)
16−add_dependencies(testDirectionalDragArea DirectionalDragAreaTestExec UbutunGesturesTestQmlFiles)
17−
18−add_executable(DirectionalDragAreaTestExec tst_DirectionalDragArea.cpp)
19−qt5_use_modules(DirectionalDragAreaTestExec Test Core Qml Gui Quick)
20−target_link_libraries(DirectionalDragAreaTestExec UbuntuGestureQml)
21−
22−add_definitions(-DUBUNTU_GESTURES_PLUGIN_DIR="${CMAKE_BINARY_DIR}/plugins")
23−
24file(GLOB qmlFiles *.qml)
8file(GLOB qmlFiles *.qml)
25add_custom_target(UbuntuGesturesTestQmlFiles ALL
9add_custom_target(UbuntuGesturesTestQmlFiles ALL
26 COMMAND cp ${qmlFiles} ${CMAKE_CURRENT_BINARY_DIR}
10 COMMAND cp ${qmlFiles} ${CMAKE_CURRENT_BINARY_DIR}
27 DEPENDS ${qmlFiles}
11 DEPENDS ${qmlFiles}
28)
12)
29
13
30−########## other tests
14+add_definitions(-DUBUNTU_GESTURES_PLUGIN_DIR="${CMAKE_BINARY_DIR}/plugins")
15+
16+macro(add_gesture_ui_test CLASSNAME)
17+ set(testCommand
18+ LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/plugins/Ubuntu/Gestures
19+ ${CMAKE_CURRENT_BINARY_DIR}/${CLASSNAME}TestExec
20+ -o ${CMAKE_BINARY_DIR}/${CLASSNAME}Test.xml,xunitxml
21+ -o -,txt)
22+
23+ add_custom_target(test${CLASSNAME} ${testCommand})
24+ add_dependencies(qmluitests test${CLASSNAME})
25+ add_dependencies(test${CLASSNAME} ${CLASSNAME}TestExec UbuntuGesturesTestQmlFiles)
26+
27+ add_executable(${CLASSNAME}TestExec tst_${CLASSNAME}.cpp GestureTest.cpp)
28+ qt5_use_modules(${CLASSNAME}TestExec Test Core Qml Gui Quick)
29+ target_link_libraries(${CLASSNAME}TestExec UbuntuGestureQml)
30+ add_manual_qml_test(. ${CLASSNAME} IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
31+endmacro(add_gesture_ui_test)
31
32
32macro(add_gesture_test CLASSNAME)
33macro(add_gesture_test CLASSNAME)
33 set(testCommand
34 set(testCommand
@@ -43,5 +44,6 @@ macro(add_gesture_test CLASSNAME)
43 target_link_libraries(${CLASSNAME}TestExec UbuntuGestureQml)
44 target_link_libraries(${CLASSNAME}TestExec UbuntuGestureQml)
44endmacro(add_gesture_test)
45endmacro(add_gesture_test)
45
46
47+add_gesture_ui_test(DirectionalDragArea)
46add_gesture_test(Damper)
48add_gesture_test(Damper)
47add_gesture_test(AxisVelocityCalculator)
49add_gesture_test(AxisVelocityCalculator)
tests/plugins/Ubuntu/Gestures/DownwardsLauncher.qml+2−10
@@ -31,10 +31,7 @@ Item {
31 y: followDragArea()
31 y: followDragArea()
32
32
33 function followDragArea() {
33 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
38 }
35 }
39 }
36 }
40
37
@@ -66,15 +63,10 @@ Item {
66 dragAreaRect.opacity = 0.3
63 dragAreaRect.opacity = 0.3
67 launcher.y = Qt.binding(launcher.followDragArea)
64 launcher.y = Qt.binding(launcher.followDragArea)
68 break;
65 break;
69− case DirectionalDragArea.Recognized:
66+ defaut: // DirectionalDragArea.Recognized:
70 dragAreaRect.color = "green"
67 dragAreaRect.color = "green"
71 dragAreaRect.opacity = 0.5
68 dragAreaRect.opacity = 0.5
72 break;
69 break;
73− default: //case DirectionalDragArea.Rejected:
74− dragAreaRect.color = "red"
75− dragAreaRect.opacity = 0.5
76− launcher.y = -launcher.height
77− break;
78 }
70 }
79 }
71 }
80
72
tests/plugins/Ubuntu/Gestures/GestureTest.cppnew 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
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "GestureTest.h"
18+
19+#include <qpa/qwindowsysteminterface.h>
20+#include <QQmlEngine>
21+#include <QQuickView>
22+#include <QtTest>
23+
24+GestureTest::GestureTest(const QString &qmlFilename)
25+ : QObject(), m_device(nullptr), m_view(nullptr), m_qmlFilename(qmlFilename)
26+{
27+}
28+
29+void GestureTest::initTestCase()
30+{
31+ if (!m_device) {
32+ m_device = new QTouchDevice;
33+ m_device->setType(QTouchDevice::TouchScreen);
34+ QWindowSystemInterface::registerTouchDevice(m_device);
35+ }
36+}
37+
38+void GestureTest::init()
39+{
40+ m_view = new QQuickView;
41+ m_view->setResizeMode(QQuickView::SizeViewToRootObject);
42+ m_view->engine()->addImportPath(QStringLiteral(UBUNTU_GESTURES_PLUGIN_DIR));
43+ m_view->setSource(QUrl::fromLocalFile(m_qmlFilename));
44+ m_view->show();
45+ QVERIFY(QTest::qWaitForWindowExposed(m_view));
46+ QVERIFY(m_view->rootObject() != 0);
47+ qApp->processEvents();
48+}
49+
50+void GestureTest::cleanup()
51+{
52+ delete m_view;
53+ m_view = nullptr;
54+}
plugins/Unity/genericpreview.h → tests/plugins/Ubuntu/Gestures/GestureTest.hrenamed+19−19
@@ -1,9 +1,6 @@
1/*
1/*
2 * Copyright (C) 2013 Canonical, Ltd.
2 * Copyright (C) 2013 Canonical, Ltd.
3 *
3 *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 3.
6 * the Free Software Foundation; version 3.
@@ -17,30 +14,33 @@
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
15 */
19
16
20−#ifndef GENERICPREVIEW_H
17+#ifndef GESTURETEST_H
21−#define GENERICPREVIEW_H
18+#endif // GESTURETEST_H
22−
23−// local
24−#include "preview.h"
25
19
26−// Qt
27#include <QObject>
20#include <QObject>
28−#include <QMetaType>
29
21
30−class GenericPreview : public Preview
22+class QQuickView;
23+class QTouchDevice;
24+
25+/*
26+ The common stuff among tests come here
27+ */
28+class GestureTest : public QObject
31{
29{
32 Q_OBJECT
30 Q_OBJECT
33−
34public:
31public:
35− explicit GenericPreview(QObject *parent = 0);
32+ // \param qmlFilename name of the qml file to be loaded by the QQuickView
33+ GestureTest(const QString &qmlFilename);
36
34
37−Q_SIGNALS:
35+protected Q_SLOTS:
38− void previewChanged();
36+ void initTestCase(); // will be called before the first test function is executed
37+ virtual void init(); // called right before each and every test function is executed
38+ virtual void cleanup(); // called right after each and every test function is executed
39
39
40protected:
40protected:
41− void setUnityPreview(unity::dash::Preview::Ptr unityPreview) override;
41+ QTouchDevice *m_device;
42+ QQuickView *m_view;
43+ QString m_qmlFilename;
42};
44};
43
45
44−Q_DECLARE_METATYPE(GenericPreview *)
46+#define GESTURETEST_H
45−
46−#endif
tests/plugins/Ubuntu/Gestures/LeftwardsLauncher.qml+5−13
@@ -32,13 +32,10 @@ Item {
32 y: 0
32 y: 0
33
33
34 function followDragArea() {
34 function followDragArea() {
35− if (dragArea.status === DirectionalDragArea.Rejected)
36− return root.width
37− else
38− return dragArea.distance > -width ?
35+ return dragArea.distance > -width ?
39− root.width + dragArea.distance
36+ root.width + dragArea.distance
40− :
37+ :
41− root.width - width
38+ root.width - width
42 }
39 }
43 }
40 }
44
41
@@ -69,15 +66,10 @@ Item {
69 dragAreaRect.opacity = 0.3
66 dragAreaRect.opacity = 0.3
70 launcher.x = Qt.binding(launcher.followDragArea)
67 launcher.x = Qt.binding(launcher.followDragArea)
71 break;
68 break;
72− case DirectionalDragArea.Recognized:
69+ default: //case DirectionalDragArea.Recognized:
73 dragAreaRect.color = "green"
70 dragAreaRect.color = "green"
74 dragAreaRect.opacity = 0.5
71 dragAreaRect.opacity = 0.5
75 break;
72 break;
76− default: //case DirectionalDragArea.Rejected:
77− dragAreaRect.color = "red"
78− dragAreaRect.opacity = 0.5
79− launcher.x = -launcher.height
80− break;
81 }
73 }
82 }
74 }
83
75
tests/plugins/Ubuntu/Gestures/RightwardsLauncher.qml+3−10
@@ -19,6 +19,7 @@ import Ubuntu.Gestures 0.1
19import Ubuntu.Components 0.1
19import Ubuntu.Components 0.1
20
20
21Item {
21Item {
22+ objectName: "rightwardsLauncher"
22
23
23 function reset() { launcher.x = -launcher.width }
24 function reset() { launcher.x = -launcher.width }
24
25
@@ -31,10 +32,7 @@ Item {
31 y: 0
32 y: 0
32
33
33 function followDragArea() {
34 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
38 }
36 }
39 }
37 }
40
38
@@ -66,15 +64,10 @@ Item {
66 dragAreaRect.opacity = 0.3
64 dragAreaRect.opacity = 0.3
67 launcher.x = Qt.binding(launcher.followDragArea)
65 launcher.x = Qt.binding(launcher.followDragArea)
68 break;
66 break;
69− case DirectionalDragArea.Recognized:
67+ default: //case DirectionalDragArea.Recognized:
70 dragAreaRect.color = "green"
68 dragAreaRect.color = "green"
71 dragAreaRect.opacity = 0.5
69 dragAreaRect.opacity = 0.5
72 break;
70 break;
73− default: //case DirectionalDragArea.Rejected:
74− dragAreaRect.color = "red"
75− dragAreaRect.opacity = 0.5
76− launcher.x = -launcher.height
77− break;
78 }
71 }
79 }
72 }
80
73
tests/plugins/Ubuntu/Gestures/UpwardsLauncher.qml+5−13
@@ -32,13 +32,10 @@ Item {
32 y: root.height
32 y: root.height
33
33
34 function followDragArea() {
34 function followDragArea() {
35− if (dragArea.status === DirectionalDragArea.Rejected)
36− return root.height
37− else
38− return dragArea.distance > -height ?
35+ return dragArea.distance > -height ?
39− root.height + dragArea.distance
36+ root.height + dragArea.distance
40− :
37+ :
41− root.height - height
38+ root.height - height
42 }
39 }
43 }
40 }
44
41
@@ -69,15 +66,10 @@ Item {
69 dragAreaRect.opacity = 0.3
66 dragAreaRect.opacity = 0.3
70 launcher.y = Qt.binding(launcher.followDragArea)
67 launcher.y = Qt.binding(launcher.followDragArea)
71 break;
68 break;
72− case DirectionalDragArea.Recognized:
69+ default: //case DirectionalDragArea.Recognized:
73 dragAreaRect.color = "green"
70 dragAreaRect.color = "green"
74 dragAreaRect.opacity = 0.5
71 dragAreaRect.opacity = 0.5
75 break;
72 break;
76− default: //case DirectionalDragArea.Rejected:
77− dragAreaRect.color = "red"
78− dragAreaRect.opacity = 0.5
79− launcher.y = -launcher.height
80− break;
81 }
73 }
82 }
74 }
83
75
tests/plugins/Ubuntu/Gestures/tst_AxisVelocityCalculator.cpp+3−3
@@ -54,12 +54,12 @@ private Q_SLOTS:
54
54
55private:
55private:
56 AxisVelocityCalculator *velCalc;
56 AxisVelocityCalculator *velCalc;
57− FakeTimeSource *fakeTimeSource;
57+ QSharedPointer<FakeTimeSource> fakeTimeSource;
58};
58};
59
59
60void tst_AxisVelocityCalculator::init()
60void tst_AxisVelocityCalculator::init()
61{
61{
62− fakeTimeSource = new FakeTimeSource;
62+ fakeTimeSource.reset(new FakeTimeSource);
63
63
64 velCalc = new AxisVelocityCalculator;
64 velCalc = new AxisVelocityCalculator;
65 velCalc->setTimeSource(fakeTimeSource);
65 velCalc->setTimeSource(fakeTimeSource);
@@ -68,7 +68,7 @@ void tst_AxisVelocityCalculator::init()
68void tst_AxisVelocityCalculator::cleanup()
68void tst_AxisVelocityCalculator::cleanup()
69{
69{
70 delete velCalc;
70 delete velCalc;
71− delete fakeTimeSource;
71+ fakeTimeSource.reset();
72}
72}
73
73
74void tst_AxisVelocityCalculator::simpleSamples()
74void tst_AxisVelocityCalculator::simpleSamples()
tests/plugins/Ubuntu/Gestures/tst_DirectionalDragArea.cpp+326−168
@@ -16,26 +16,42 @@
16
16
17#include <QtTest/QtTest>
17#include <QtTest/QtTest>
18#include <QtCore/QObject>
18#include <QtCore/QObject>
19−#include <qpa/qwindowsysteminterface.h>
20#include <QtQuick/QQuickView>
19#include <QtQuick/QQuickView>
21#include <QtQml/QQmlEngine>
20#include <QtQml/QQmlEngine>
21+#include <QPointer>
22
22
23#include <DirectionalDragArea.h>
23#include <DirectionalDragArea.h>
24
24
25+#include "GestureTest.h"
26+
27+using namespace UbuntuGestures;
28+
25−class FakeTimer : public UbuntuGestures::AbstractTimer
29+class FakeTimer : public AbstractTimer
26{
30{
27 Q_OBJECT
31 Q_OBJECT
28public:
32public:
29− FakeTimer(QObject *parent = 0)
33+ FakeTimer(const SharedTimeSource &timeSource, QObject *parent = 0)
30− : UbuntuGestures::AbstractTimer(parent)
34+ : UbuntuGestures::AbstractTimer(parent),
35+ m_timeSource(timeSource)
31 {}
36 {}
32
37
33− virtual int interval() const { return m_duration; }
38+ int interval() const override { return m_interval; }
34− virtual void setInterval(int msecs) { m_duration = msecs; }
39+ void setInterval(int msecs) override { m_interval = msecs; }
40+ void start() override {
41+ AbstractTimer::start();
42+ m_nextTimeoutTime = m_timeSource->msecsSinceReference() + (qint64)m_interval;
43+ }
44+
45+ void emitTimeout() {
46+ m_nextTimeoutTime += m_interval;
47+ Q_EMIT timeout();
48+ }
35
49
36− void emitTimeout() {Q_EMIT timeout();}
50+ qint64 nextTimeoutTime() const { return m_nextTimeoutTime; }
37private:
51private:
38− int m_duration;
52+ int m_interval;
53+ SharedTimeSource m_timeSource;
54+ qint64 m_nextTimeoutTime;
39};
55};
40
56
41class FakeTimeSource : public UbuntuGestures::TimeSource
57class FakeTimeSource : public UbuntuGestures::TimeSource
@@ -46,15 +62,12 @@ public:
46 qint64 m_msecsSinceReference;
62 qint64 m_msecsSinceReference;
47};
63};
48
64
49−class tst_DirectionalDragArea: public QObject
65+class tst_DirectionalDragArea: public GestureTest
50{
66{
51 Q_OBJECT
67 Q_OBJECT
52public:
68public:
53− tst_DirectionalDragArea() : device(0) { }
69+ tst_DirectionalDragArea();
54private Q_SLOTS:
70private Q_SLOTS:
55− void initTestCase(); // will be called before the first test function is executed
56− void cleanupTestCase(); // will be called after the last test function was executed.
57−
58 void init(); // called right before each and every test function is executed
71 void init(); // called right before each and every test function is executed
59 void cleanup(); // called right after each and every test function is executed
72 void cleanup(); // called right after each and every test function is executed
60
73
@@ -67,64 +80,54 @@ private Q_SLOTS:
67 void maxSilenceTime();
80 void maxSilenceTime();
68 void sceneXAndX();
81 void sceneXAndX();
69 void sceneYAndY();
82 void sceneYAndY();
70− void emitDraggingChangedOnDirectRecognition();
83+ void twoFingerTap();
84+ void movingDDA();
85+ void ignoreOldFinger();
71
86
72private:
87private:
73− QQuickView *createView();
88+ void passTime(qint64 timeSpan);
74− QQuickView *view;
75− QTouchDevice *device;
76 FakeTimer *fakeTimer;
89 FakeTimer *fakeTimer;
77− FakeTimeSource *fakeTimeSource;
90+ QSharedPointer<FakeTimeSource> fakeTimeSource;
78};
91};
79
92
80−void tst_DirectionalDragArea::initTestCase()
93+tst_DirectionalDragArea::tst_DirectionalDragArea()
81−{
94+ : GestureTest(QStringLiteral("tst_DirectionalDragArea.qml"))
82− if (!device) {
83− device = new QTouchDevice;
84− device->setType(QTouchDevice::TouchScreen);
85− QWindowSystemInterface::registerTouchDevice(device);
86− }
87−
88− view = 0;
89−}
90−
91−void tst_DirectionalDragArea::cleanupTestCase()
92{
95{
93}
96}
94
97
95void tst_DirectionalDragArea::init()
98void tst_DirectionalDragArea::init()
96{
99{
97− view = createView();
100+ GestureTest::init();
98− view->setSource(QUrl::fromLocalFile("edgeDragExample.qml"));
101+
99− view->show();
102+ fakeTimeSource.reset(new FakeTimeSource);
100− QVERIFY(QTest::qWaitForWindowExposed(view));
101− QVERIFY(view->rootObject() != 0);
102− qApp->processEvents();
103−
104− fakeTimer = new FakeTimer;
103+ fakeTimer = new FakeTimer(fakeTimeSource);
105− fakeTimeSource = new FakeTimeSource;
106}
104}
107
105
108void tst_DirectionalDragArea::cleanup()
106void tst_DirectionalDragArea::cleanup()
109{
107{
110− delete view;
111− view = 0;
112−
113 delete fakeTimer;
108 delete fakeTimer;
114 fakeTimer = 0;
109 fakeTimer = 0;
115
110
116− delete fakeTimeSource;
111+ fakeTimeSource.reset();
117− fakeTimeSource = 0;
112+
113+ GestureTest::cleanup();
118}
114}
119
115
120−QQuickView *tst_DirectionalDragArea::createView()
116+void tst_DirectionalDragArea::passTime(qint64 timeSpan)
121{
117{
122− QQuickView *window = new QQuickView(0);
118+ qint64 finalTime = fakeTimeSource->m_msecsSinceReference + timeSpan;
123− window->setResizeMode(QQuickView::SizeRootObjectToView);
119+
124− window->resize(600, 600);
120+ if (fakeTimer->isRunning() && finalTime >= fakeTimer->nextTimeoutTime()) {
125− window->engine()->addImportPath(QLatin1String(UBUNTU_GESTURES_PLUGIN_DIR));
121+ fakeTimeSource->m_msecsSinceReference = fakeTimer->nextTimeoutTime();
122+ fakeTimer->emitTimeout();
126
123
127− return window;
124+ qint64 timeSpanRemainder = finalTime - fakeTimeSource->m_msecsSinceReference;
125+ if (timeSpanRemainder > 0) {
126+ passTime(timeSpanRemainder);
127+ }
128+ } else {
129+ fakeTimeSource->m_msecsSinceReference = finalTime;
130+ }
128}
131}
129
132
130namespace {
133namespace {
@@ -180,25 +183,28 @@ void tst_DirectionalDragArea::edgeDrag()
180 QFETCH(QString, dragAreaObjectName);
183 QFETCH(QString, dragAreaObjectName);
181 QFETCH(qreal, wideningAngleMultiplier);
184 QFETCH(qreal, wideningAngleMultiplier);
182 QFETCH(qreal, dragDistanceFactor);
185 QFETCH(qreal, dragDistanceFactor);
183− QFETCH(int, expectedGestureRecognition);
186+ QFETCH(bool, expectGestureRecognition);
184
187
185 DirectionalDragArea *edgeDragArea =
188 DirectionalDragArea *edgeDragArea =
186− view->rootObject()->findChild<DirectionalDragArea*>(dragAreaObjectName);
189+ m_view->rootObject()->findChild<DirectionalDragArea*>(dragAreaObjectName);
187 QVERIFY(edgeDragArea != 0);
190 QVERIFY(edgeDragArea != 0);
188 edgeDragArea->setRecognitionTimer(fakeTimer);
191 edgeDragArea->setRecognitionTimer(fakeTimer);
189 edgeDragArea->setTimeSource(fakeTimeSource);
192 edgeDragArea->setTimeSource(fakeTimeSource);
190
193
191 QSignalSpy draggingSpy(edgeDragArea, SIGNAL(draggingChanged(bool)));
194 QSignalSpy draggingSpy(edgeDragArea, SIGNAL(draggingChanged(bool)));
192
195
193− QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, view);
196+ QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, m_view);
194 QPointF touchPoint = initialTouchPos;
197 QPointF touchPoint = initialTouchPos;
195
198
196 qreal desiredDragDistance = edgeDragArea->distanceThreshold()*dragDistanceFactor;
199 qreal desiredDragDistance = edgeDragArea->distanceThreshold()*dragDistanceFactor;
197 QPointF dragDirectionVector = calculateDirectionVector(edgeDragArea,
200 QPointF dragDirectionVector = calculateDirectionVector(edgeDragArea,
198 wideningAngleMultiplier);
201 wideningAngleMultiplier);
199− QPointF touchMovement = dragDirectionVector * (edgeDragArea->distanceThreshold() * 0.1f);
202+ qreal movementStepDistance = edgeDragArea->distanceThreshold() * 0.1f;
203+ QPointF touchMovement = dragDirectionVector * movementStepDistance;
204+ int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
205+ int movementTimeStepMs = (edgeDragArea->compositionTime() * 1.5f) / totalMovementSteps;
200
206
201− QTest::touchEvent(view, device).press(0, touchPoint.toPoint());
207+ QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
202
208
203 QCOMPARE(draggingSpy.count(), 1);
209 QCOMPARE(draggingSpy.count(), 1);
204 QCOMPARE(edgeDragArea->dragging(), true);
210 QCOMPARE(edgeDragArea->dragging(), true);
@@ -208,23 +214,24 @@ void tst_DirectionalDragArea::edgeDrag()
208 // in order to make it easier to leave it by dragging at an angle
214 // in order to make it easier to leave it by dragging at an angle
209 // slightly bigger than the widening angle
215 // slightly bigger than the widening angle
210 touchPoint += createTouchDeviation(edgeDragArea);
216 touchPoint += createTouchDeviation(edgeDragArea);
211− QTest::touchEvent(view, device).move(0, touchPoint.toPoint());
217+ QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
212 }
218 }
213
219
214− do {
220+ for (int i = 0; i < totalMovementSteps; ++i) {
215 touchPoint += touchMovement;
221 touchPoint += touchMovement;
222+ passTime(movementTimeStepMs);
216− QTest::touchEvent(view, device).move(0, touchPoint.toPoint());
223+ QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
217− } while ((touchPoint - initialTouchPos).manhattanLength() < desiredDragDistance);
224+ }
218
225
219− if (expectedGestureRecognition)
226+ if (expectGestureRecognition)
220 QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
227 QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
221
228
222− if (edgeDragArea->status() == DirectionalDragArea::Rejected) {
229+ if (edgeDragArea->status() == DirectionalDragArea::WaitingForTouch) {
223 QCOMPARE(edgeDragArea->dragging(), false);
230 QCOMPARE(edgeDragArea->dragging(), false);
224 QCOMPARE(draggingSpy.count(), 2);
231 QCOMPARE(draggingSpy.count(), 2);
225 }
232 }
226
233
227− QTest::touchEvent(view, device).release(0, touchPoint.toPoint());
234+ QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
228
235
229 QCOMPARE(draggingSpy.count(), 2);
236 QCOMPARE(draggingSpy.count(), 2);
230 QCOMPARE(edgeDragArea->dragging(), false);
237 QCOMPARE(edgeDragArea->dragging(), false);
@@ -235,49 +242,49 @@ void tst_DirectionalDragArea::edgeDrag_data()
235 QTest::addColumn<QString>("dragAreaObjectName");
242 QTest::addColumn<QString>("dragAreaObjectName");
236 QTest::addColumn<qreal>("wideningAngleMultiplier");
243 QTest::addColumn<qreal>("wideningAngleMultiplier");
237 QTest::addColumn<qreal>("dragDistanceFactor");
244 QTest::addColumn<qreal>("dragDistanceFactor");
238− QTest::addColumn<int>("expectedGestureRecognition");
245+ QTest::addColumn<bool>("expectGestureRecognition");
239
246
240 QTest::newRow("rightwards, tiny drag")
247 QTest::newRow("rightwards, tiny drag")
241− << "hpDragArea" << 0.0 << 0.2 << 0;
248+ << "hpDragArea" << 0.0 << 0.2 << false;
242
249
243 QTest::newRow("rightwards, straight drag")
250 QTest::newRow("rightwards, straight drag")
244− << "hpDragArea" << 0.0 << 3.0 << 1;
251+ << "hpDragArea" << 0.0 << 3.0 << true;
245
252
246 QTest::newRow("rightwards, diagonal drag")
253 QTest::newRow("rightwards, diagonal drag")
247− << "hpDragArea" << 0.9 << 3.0 << 1;
254+ << "hpDragArea" << 0.9 << 3.0 << true;
248
255
249 QTest::newRow("rightwards, overly diagonal drag")
256 QTest::newRow("rightwards, overly diagonal drag")
250− << "hpDragArea" << 2.0 << 3.0 << 0;
257+ << "hpDragArea" << 2.0 << 3.0 << false;
251
258
252 QTest::newRow("leftwards, tiny drag")
259 QTest::newRow("leftwards, tiny drag")
253− << "hnDragArea" << 0.0 << 0.2 << 0;
260+ << "hnDragArea" << 0.0 << 0.2 << false;
254
261
255 QTest::newRow("leftwards, straight drag")
262 QTest::newRow("leftwards, straight drag")
256− << "hnDragArea" << 0.0 << 3.0 << 1;
263+ << "hnDragArea" << 0.0 << 3.0 << true;
257
264
258 QTest::newRow("leftwards, diagonal drag")
265 QTest::newRow("leftwards, diagonal drag")
259− << "hnDragArea" << 0.9 << 3.0 << 1;
266+ << "hnDragArea" << 0.9 << 3.0 << true;
260
267
261 QTest::newRow("downwards, tiny drag")
268 QTest::newRow("downwards, tiny drag")
262− << "vpDragArea" << 0.0 << 0.2 << 0;
269+ << "vpDragArea" << 0.0 << 0.2 << false;
263
270
264 QTest::newRow("downwards, straight drag")
271 QTest::newRow("downwards, straight drag")
265− << "vpDragArea" << 0.0 << 3.0 << 1;
272+ << "vpDragArea" << 0.0 << 3.0 << true;
266
273
267 QTest::newRow("downwards, diagonal drag")
274 QTest::newRow("downwards, diagonal drag")
268− << "vpDragArea" << 0.9 << 3.0 << 1;
275+ << "vpDragArea" << 0.9 << 3.0 << true;
269
276
270 QTest::newRow("upwards, tiny drag")
277 QTest::newRow("upwards, tiny drag")
271− << "vnDragArea" << 0.0 << 0.2 << 0;
278+ << "vnDragArea" << 0.0 << 0.2 << false;
272
279
273 QTest::newRow("upwards, straight drag")
280 QTest::newRow("upwards, straight drag")
274− << "vnDragArea" << 0.0 << 3.0 << 1;
281+ << "vnDragArea" << 0.0 << 3.0 << true;
275
282
276 QTest::newRow("upwards, diagonal drag")
283 QTest::newRow("upwards, diagonal drag")
277− << "vnDragArea" << 0.9 << 3.0 << 1;
284+ << "vnDragArea" << 0.9 << 3.0 << true;
278
285
279 QTest::newRow("upwards, overly diagonal drag")
286 QTest::newRow("upwards, overly diagonal drag")
280− << "vnDragArea" << 2.0 << 3.0 << 0;
287+ << "vnDragArea" << 2.0 << 3.0 << false;
281}
288}
282
289
283/*
290/*
@@ -288,39 +295,47 @@ void tst_DirectionalDragArea::edgeDrag_data()
288void tst_DirectionalDragArea::dragWithShortDirectionChange()
295void tst_DirectionalDragArea::dragWithShortDirectionChange()
289{
296{
290 DirectionalDragArea *edgeDragArea =
297 DirectionalDragArea *edgeDragArea =
291− view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
298+ m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
292 QVERIFY(edgeDragArea != 0);
299 QVERIFY(edgeDragArea != 0);
293 edgeDragArea->setRecognitionTimer(fakeTimer);
300 edgeDragArea->setRecognitionTimer(fakeTimer);
294 edgeDragArea->setTimeSource(fakeTimeSource);
301 edgeDragArea->setTimeSource(fakeTimeSource);
295
302
296− QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, view);
303+ QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, m_view);
297 QPointF touchPoint = initialTouchPos;
304 QPointF touchPoint = initialTouchPos;
298
305
299 qreal desiredDragDistance = edgeDragArea->distanceThreshold()*2.0;
306 qreal desiredDragDistance = edgeDragArea->distanceThreshold()*2.0;
300 QPointF dragDirectionVector(1.0, 0.0);
307 QPointF dragDirectionVector(1.0, 0.0);
301− QPointF touchMovement = dragDirectionVector * (edgeDragArea->distanceThreshold() * 0.1f);
308+ qreal touchStepDistance = edgeDragArea->distanceThreshold() * 0.1f;
309+ // make sure we are above minimum speed
310+ int touchStepTimeMs = (touchStepDistance / (edgeDragArea->minSpeed() * 5.0f)) * 1000.0f;
311+ QPointF touchMovement = dragDirectionVector * touchStepDistance;
302
312
303− QTest::touchEvent(view, device).press(0, touchPoint.toPoint());
313+ QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
304
314
305 // Move a bit in the proper direction
315 // Move a bit in the proper direction
306 for (int i=0; i < 3; ++i) {
316 for (int i=0; i < 3; ++i) {
307 touchPoint += touchMovement;
317 touchPoint += touchMovement;
318+ passTime(touchStepTimeMs);
308− QTest::touchEvent(view, device).move(0, touchPoint.toPoint());
319+ QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
309 }
320 }
310
321
311 // Then a sudden and small movement to the opposite direction
322 // Then a sudden and small movement to the opposite direction
312− touchPoint -= dragDirectionVector * (edgeDragArea->maxDeviation() * 0.7);
323+ touchPoint -= touchMovement*0.2;
324+ passTime(touchStepTimeMs*0.2);
313− QTest::touchEvent(view, device).move(0, touchPoint.toPoint());
325+ QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
314
326
315− // And then resume movment in the correct direction until it crosses the distance threshold.
327+ // And then resume movment in the correct direction until it crosses the distance and time
328+ // thresholds.
316 do {
329 do {
317 touchPoint += touchMovement;
330 touchPoint += touchMovement;
331+ passTime(touchStepTimeMs);
318− QTest::touchEvent(view, device).move(0, touchPoint.toPoint());
332+ QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
319− } while ((touchPoint - initialTouchPos).manhattanLength() < desiredDragDistance);
333+ } while ((touchPoint - initialTouchPos).manhattanLength() < desiredDragDistance
334+ || fakeTimeSource->m_msecsSinceReference < (edgeDragArea->compositionTime() * 1.5f));
320
335
321 QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
336 QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
322
337
323− QTest::touchEvent(view, device).release(0, touchPoint.toPoint());
338+ QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
324}
339}
325
340
326/*
341/*
@@ -329,53 +344,50 @@ void tst_DirectionalDragArea::dragWithShortDirectionChange()
329 */
344 */
330void tst_DirectionalDragArea::minSpeed()
345void tst_DirectionalDragArea::minSpeed()
331{
346{
332− QFETCH(int, minSpeedMsecsDeviation);
347+ QFETCH(qreal, minSpeed);
348+ QFETCH(qreal, speed);
333 QFETCH(int, expectedStatusAfterSpeedCheck);
349 QFETCH(int, expectedStatusAfterSpeedCheck);
334
350
335 DirectionalDragArea *edgeDragArea =
351 DirectionalDragArea *edgeDragArea =
336− view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
352+ m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
337 QVERIFY(edgeDragArea != 0);
353 QVERIFY(edgeDragArea != 0);
338 edgeDragArea->setRecognitionTimer(fakeTimer);
354 edgeDragArea->setRecognitionTimer(fakeTimer);
339 edgeDragArea->setTimeSource(fakeTimeSource);
355 edgeDragArea->setTimeSource(fakeTimeSource);
340
356
357+ // A really long, unattainable, number. We don't want it getting recognized before
358+ // the speed checks we want have been performed
359+ edgeDragArea->setDistanceThreshold(500000);
360+
361+ edgeDragArea->setMinSpeed(minSpeed);
362+
341− QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, view);
363+ QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, m_view);
342 QPointF touchPoint = initialTouchPos;
364 QPointF touchPoint = initialTouchPos;
343
365
344 QPointF dragDirectionVector(1.0, 0.0);
366 QPointF dragDirectionVector(1.0, 0.0);
345− qreal distanceStep = edgeDragArea->distanceThreshold() * 0.1f;
367+ qint64 timeStepMsecs = 10;
368+ qreal distanceStep = (speed / 1000.0f) * timeStepMsecs;
346 QPointF touchMovement = dragDirectionVector * distanceStep;
369 QPointF touchMovement = dragDirectionVector * distanceStep;
347− qreal minSpeedMsecs = edgeDragArea->minSpeed() / 1000.0;
348− qint64 timeStepMsecs = qFloor(distanceStep / minSpeedMsecs) + minSpeedMsecsDeviation;
349
370
350− // if it fails it means the params set in the QML file are not in harmony with the values
371+ QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
351− // used in this test
352− Q_ASSERT(timeStepMsecs > 0);
353
372
354− fakeTimeSource->m_msecsSinceReference = 0;
373+ // Move for a while to ensure our speed check is performed a couple of times
355− QTest::touchEvent(view, device).press(0, touchPoint.toPoint());
356−
357− // Move a bit in the proper direction
358− for (int i=0; i < 4; ++i) {
374+ for (int i=0; i < 20; ++i) {
359 touchPoint += touchMovement;
375 touchPoint += touchMovement;
360− fakeTimeSource->m_msecsSinceReference += timeStepMsecs;
376+ passTime(timeStepMsecs);
361− QTest::touchEvent(view, device).move(0, touchPoint.toPoint());
377+ QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
362 }
378 }
363
379
364− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
365−
366− // Force the periodic speed check.
367− fakeTimer->emitTimeout();
368−
369 QCOMPARE((int)edgeDragArea->status(), expectedStatusAfterSpeedCheck);
380 QCOMPARE((int)edgeDragArea->status(), expectedStatusAfterSpeedCheck);
370}
381}
371
382
372void tst_DirectionalDragArea::minSpeed_data()
383void tst_DirectionalDragArea::minSpeed_data()
373{
384{
374− QTest::addColumn<int>("minSpeedMsecsDeviation");
385+ QTest::addColumn<qreal>("minSpeed");
386+ QTest::addColumn<qreal>("speed");
375 QTest::addColumn<int>("expectedStatusAfterSpeedCheck");
387 QTest::addColumn<int>("expectedStatusAfterSpeedCheck");
376
388
377− QTest::newRow("slower than minSpeed") << 20 << (int)DirectionalDragArea::Rejected;
389+ QTest::newRow("slower than minSpeed") << 100.0 << 50.0 << (int)DirectionalDragArea::WaitingForTouch;
378− QTest::newRow("faster than minSpeed") << -20 << (int)DirectionalDragArea::Undecided;
390+ QTest::newRow("faster than minSpeed") << 100.0 << 150.0 << (int)DirectionalDragArea::Undecided;
379}
391}
380
392
381/*
393/*
@@ -386,37 +398,42 @@ void tst_DirectionalDragArea::minSpeed_data()
386void tst_DirectionalDragArea::recognitionTimerUsage()
398void tst_DirectionalDragArea::recognitionTimerUsage()
387{
399{
388 DirectionalDragArea *edgeDragArea =
400 DirectionalDragArea *edgeDragArea =
389− view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
401+ m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
390 QVERIFY(edgeDragArea != 0);
402 QVERIFY(edgeDragArea != 0);
391 edgeDragArea->setRecognitionTimer(fakeTimer);
403 edgeDragArea->setRecognitionTimer(fakeTimer);
392 edgeDragArea->setTimeSource(fakeTimeSource);
404 edgeDragArea->setTimeSource(fakeTimeSource);
393
405
406+ // don't let it interfere with our test
407+ edgeDragArea->setMinSpeed(0.0);
408+
409+ int timeStepMs = 5; // some arbitrary small value.
410+
394− QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, view);
411+ QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, m_view);
395 QPointF touchPoint = initialTouchPos;
412 QPointF touchPoint = initialTouchPos;
396
413
397 QPointF dragDirectionVector(1.0, 0.0);
414 QPointF dragDirectionVector(1.0, 0.0);
398 QPointF touchMovement = dragDirectionVector * (edgeDragArea->distanceThreshold() * 0.2f);
415 QPointF touchMovement = dragDirectionVector * (edgeDragArea->distanceThreshold() * 0.2f);
399
416
417+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
400 QVERIFY(!fakeTimer->isRunning());
418 QVERIFY(!fakeTimer->isRunning());
401
419
402− QTest::touchEvent(view, device).press(0, touchPoint.toPoint());
420+ QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
403
421
422+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
404 QVERIFY(fakeTimer->isRunning());
423 QVERIFY(fakeTimer->isRunning());
405
424
406− // Move a bit in the proper direction
425+ // Move beyond distance threshold and composition time to ensure recognition
407− for (int i=0; i < 3; ++i) {
426+ while (fakeTimeSource->m_msecsSinceReference <= edgeDragArea->compositionTime() ||
408− touchPoint += touchMovement;
427+ (touchPoint - initialTouchPos).manhattanLength() <= edgeDragArea->distanceThreshold()) {
409− QTest::touchEvent(view, device).move(0, touchPoint.toPoint());
410− }
411
428
412− QVERIFY(fakeTimer->isRunning());
429+ QCOMPARE(edgeDragArea->status() == DirectionalDragArea::Undecided, fakeTimer->isRunning());
413
430
414− // Move beyond distance threshold
415− touchPoint += 3*touchMovement;
431+ touchPoint += touchMovement;
432+ passTime(timeStepMs);
416− QTest::touchEvent(view, device).move(0, touchPoint.toPoint());
433+ QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
434+ }
417
435
418 QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
436 QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
419−
420 QVERIFY(!fakeTimer->isRunning());
437 QVERIFY(!fakeTimer->isRunning());
421}
438}
422
439
@@ -427,34 +444,28 @@ void tst_DirectionalDragArea::recognitionTimerUsage()
427void tst_DirectionalDragArea::maxSilenceTime()
444void tst_DirectionalDragArea::maxSilenceTime()
428{
445{
429 DirectionalDragArea *edgeDragArea =
446 DirectionalDragArea *edgeDragArea =
430− view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
447+ m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
431 QVERIFY(edgeDragArea != 0);
448 QVERIFY(edgeDragArea != 0);
432 edgeDragArea->setRecognitionTimer(fakeTimer);
449 edgeDragArea->setRecognitionTimer(fakeTimer);
433 edgeDragArea->setTimeSource(fakeTimeSource);
450 edgeDragArea->setTimeSource(fakeTimeSource);
434
451
452+ // Make sure this property is not disabled
453+ edgeDragArea->setMaxSilenceTime(100);
454+
435− QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, view);
455+ QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, m_view);
436 QPointF touchPoint = initialTouchPos;
456 QPointF touchPoint = initialTouchPos;
437
457
438− fakeTimeSource->m_msecsSinceReference = 0;
439− QTest::touchEvent(view, device).press(0, touchPoint.toPoint());
458+ QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
440
459
441 QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
460 QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
461+ QVERIFY(fakeTimer->isRunning());
442
462
443− int neededTimeouts = qCeil((qreal)edgeDragArea->maxSilenceTime() / (qreal)fakeTimer->interval());
463+ // Force timer to timeout until after maxSilenceTime has been reached
444− if ((edgeDragArea->maxSilenceTime() % fakeTimer->interval()) == 0) {
464+ while (fakeTimeSource->m_msecsSinceReference < edgeDragArea->maxSilenceTime()) {
445− ++neededTimeouts;
465+ passTime(fakeTimer->interval());
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− }
455 }
466 }
456
467
457− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Rejected);
468+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
458}
469}
459
470
460/*
471/*
@@ -464,21 +475,20 @@ void tst_DirectionalDragArea::maxSilenceTime()
464void tst_DirectionalDragArea::sceneXAndX()
475void tst_DirectionalDragArea::sceneXAndX()
465{
476{
466 DirectionalDragArea *edgeDragArea =
477 DirectionalDragArea *edgeDragArea =
467− view->rootObject()->findChild<DirectionalDragArea*>("hnDragArea");
478+ m_view->rootObject()->findChild<DirectionalDragArea*>("hnDragArea");
468 QVERIFY(edgeDragArea != 0);
479 QVERIFY(edgeDragArea != 0);
469 edgeDragArea->setRecognitionTimer(fakeTimer);
480 edgeDragArea->setRecognitionTimer(fakeTimer);
470 edgeDragArea->setTimeSource(fakeTimeSource);
481 edgeDragArea->setTimeSource(fakeTimeSource);
471
482
472− QPointF touchScenePos(view->width() - (edgeDragArea->width()/2.0f), view->height()/2.0f);
483+ QPointF touchScenePos(m_view->width() - (edgeDragArea->width()/2.0f), m_view->height()/2.0f);
473
484
474− fakeTimeSource->m_msecsSinceReference = 0;
475− QTest::touchEvent(view, device).press(0, touchScenePos.toPoint());
485+ QTest::touchEvent(m_view, m_device).press(0, touchScenePos.toPoint());
476
486
477 QSignalSpy touchXSpy(edgeDragArea, SIGNAL(touchXChanged(qreal)));
487 QSignalSpy touchXSpy(edgeDragArea, SIGNAL(touchXChanged(qreal)));
478 QSignalSpy touchSceneXSpy(edgeDragArea, SIGNAL(touchSceneXChanged(qreal)));
488 QSignalSpy touchSceneXSpy(edgeDragArea, SIGNAL(touchSceneXChanged(qreal)));
479
489
480− touchScenePos.rx() = view->width() / 2;
490+ touchScenePos.rx() = m_view->width() / 2;
481− QTest::touchEvent(view, device).move(0, touchScenePos.toPoint());
491+ QTest::touchEvent(m_view, m_device).move(0, touchScenePos.toPoint());
482
492
483 QCOMPARE(touchXSpy.count(), 1);
493 QCOMPARE(touchXSpy.count(), 1);
484 QCOMPARE(touchSceneXSpy.count(), 1);
494 QCOMPARE(touchSceneXSpy.count(), 1);
@@ -493,21 +503,20 @@ void tst_DirectionalDragArea::sceneXAndX()
493void tst_DirectionalDragArea::sceneYAndY()
503void tst_DirectionalDragArea::sceneYAndY()
494{
504{
495 DirectionalDragArea *edgeDragArea =
505 DirectionalDragArea *edgeDragArea =
496− view->rootObject()->findChild<DirectionalDragArea*>("vnDragArea");
506+ m_view->rootObject()->findChild<DirectionalDragArea*>("vnDragArea");
497 QVERIFY(edgeDragArea != 0);
507 QVERIFY(edgeDragArea != 0);
498 edgeDragArea->setRecognitionTimer(fakeTimer);
508 edgeDragArea->setRecognitionTimer(fakeTimer);
499 edgeDragArea->setTimeSource(fakeTimeSource);
509 edgeDragArea->setTimeSource(fakeTimeSource);
500
510
501− QPointF touchScenePos(view->width()/2.0f, view->height() - (edgeDragArea->height()/2.0f));
511+ QPointF touchScenePos(m_view->width()/2.0f, m_view->height() - (edgeDragArea->height()/2.0f));
502
512
503− fakeTimeSource->m_msecsSinceReference = 0;
504− QTest::touchEvent(view, device).press(0, touchScenePos.toPoint());
513+ QTest::touchEvent(m_view, m_device).press(0, touchScenePos.toPoint());
505
514
506 QSignalSpy touchYSpy(edgeDragArea, SIGNAL(touchYChanged(qreal)));
515 QSignalSpy touchYSpy(edgeDragArea, SIGNAL(touchYChanged(qreal)));
507 QSignalSpy touchSceneYSpy(edgeDragArea, SIGNAL(touchSceneYChanged(qreal)));
516 QSignalSpy touchSceneYSpy(edgeDragArea, SIGNAL(touchSceneYChanged(qreal)));
508
517
509− touchScenePos.ry() = view->height() / 2;
518+ touchScenePos.ry() = m_view->height() / 2;
510− QTest::touchEvent(view, device).move(0, touchScenePos.toPoint());
519+ QTest::touchEvent(m_view, m_device).move(0, touchScenePos.toPoint());
511
520
512 QCOMPARE(touchYSpy.count(), 1);
521 QCOMPARE(touchYSpy.count(), 1);
513 QCOMPARE(touchSceneYSpy.count(), 1);
522 QCOMPARE(touchSceneYSpy.count(), 1);
@@ -516,34 +525,183 @@ void tst_DirectionalDragArea::sceneYAndY()
516}
525}
517
526
518/*
527/*
519− Emit draggingChanged() when status change from WaitingForTouch directly to Recognized.
528+ Regression test for https://bugs.launchpad.net/bugs/1228336
520− This happens when the gesture recognition is effectively disabled (e.g. by setting a
529+
521− distanceThreshold of zero)
530+ Perform a quick two-finger double-tap and check that DirectionalDragArea properly
531+ rejects those touch points. In the bug above it got confused and crashed.
522 */
532 */
523−void tst_DirectionalDragArea::emitDraggingChangedOnDirectRecognition()
533+void tst_DirectionalDragArea::twoFingerTap()
524{
534{
525 DirectionalDragArea *edgeDragArea =
535 DirectionalDragArea *edgeDragArea =
526− view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
536+ m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
527 QVERIFY(edgeDragArea != 0);
537 QVERIFY(edgeDragArea != 0);
528 edgeDragArea->setRecognitionTimer(fakeTimer);
538 edgeDragArea->setRecognitionTimer(fakeTimer);
529 edgeDragArea->setTimeSource(fakeTimeSource);
539 edgeDragArea->setTimeSource(fakeTimeSource);
530
540
531− QPointF touchPos = calculateInitialTouchPos(edgeDragArea, view);
541+ // Make touches evenly spaced along the edgeDragArea
542+ QPoint touchAPos(edgeDragArea->width()/2.0f, m_view->height()*0.33f);
543+ QPoint touchBPos(edgeDragArea->width()/2.0f, m_view->height()*0.66f);
532
544
533− QSignalSpy draggingSpy(edgeDragArea, SIGNAL(draggingChanged(bool)));
545+ qint64 timeStepMsecs = 5; // some arbitrary, small value
546+
547+ // Perform the first two-finger tap
548+ // NB: using move() instead of stationary() becasue in the latter you cannot provide
549+ // the touch position and therefore it's left with some garbage numbers.
550+ QTest::touchEvent(m_view, m_device)
551+ .press(0, touchAPos);
552+
553+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
534
554
535− // That will make it completetly skip the recognition phase ("Undecided" status).
555+ passTime(timeStepMsecs);
536− edgeDragArea->setDistanceThreshold(0.0);
556+ QTest::touchEvent(m_view, m_device)
557+ .move(0, touchAPos)
558+ .press(1, touchBPos);
559+
560+ // A second touch point appeared during recognition, reject immediately as this
561+ // can't be a single-touch gesture anymore.
562+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
563+
564+ passTime(timeStepMsecs);
565+ QTest::touchEvent(m_view, m_device)
566+ .release(0, touchAPos)
567+ .move(1, touchBPos);
568+
569+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
570+
571+ passTime(timeStepMsecs);
572+ QTest::touchEvent(m_view, m_device)
573+ .release(1, touchBPos);
537
574
538 QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
575 QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
539− QCOMPARE(edgeDragArea->dragging(), false);
540
576
541− fakeTimeSource->m_msecsSinceReference = 0;
577+ // Perform the second two-finger tap
578+
579+ passTime(timeStepMsecs);
580+ QTest::touchEvent(m_view, m_device)
581+ .press(0, touchAPos);
582+
583+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
584+
585+ passTime(timeStepMsecs);
586+ QTest::touchEvent(m_view, m_device)
587+ .move(0, touchAPos)
588+ .press(1, touchBPos);
589+
590+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
591+
592+ passTime(timeStepMsecs);
593+ QTest::touchEvent(m_view, m_device)
594+ .release(0, touchAPos)
595+ .move(1, touchBPos);
596+
597+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
598+
599+ passTime(timeStepMsecs);
600+ QTest::touchEvent(m_view, m_device)
601+ .release(1, touchBPos);
602+
603+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
604+}
605+
606+/*
607+ Tests that gesture recognition works normally even if the DirectionalDragArea moves
608+ during recognition.
609+ This effectively means that we have to do gesture recognition with scene coordinates
610+ instead of local item coordinates.
611+ */
612+void tst_DirectionalDragArea::movingDDA()
613+{
614+ QQuickItem *rightwardsLauncher = m_view->rootObject()->findChild<QQuickItem*>("rightwardsLauncher");
615+ Q_ASSERT(rightwardsLauncher != 0);
616+
617+ DirectionalDragArea *edgeDragArea =
618+ rightwardsLauncher->findChild<DirectionalDragArea*>("hpDragArea");
619+ Q_ASSERT(edgeDragArea != 0);
620+ edgeDragArea->setRecognitionTimer(fakeTimer);
621+ edgeDragArea->setTimeSource(fakeTimeSource);
622+
623+ QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, m_view);
624+ QPointF touchPoint = initialTouchPos;
625+
626+ qreal desiredDragDistance = edgeDragArea->distanceThreshold()*2.0f;
627+ QPointF dragDirectionVector(1.0f, 0.0f);
628+
629+ qreal movementStepDistance = edgeDragArea->distanceThreshold() * 0.1f;
630+ QPointF touchMovement = dragDirectionVector * movementStepDistance;
631+ int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
632+ int movementTimeStepMs = (edgeDragArea->compositionTime() * 1.5f) / totalMovementSteps;
633+
542− QTest::touchEvent(view, device).press(0, touchPos.toPoint());
634+ QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
635+
636+ // Move it far ahead along the direction of the gesture
637+ // rightwardsLauncher is a parent of our DirectionalDragArea. So moving it will move our DDA
638+ rightwardsLauncher->setX(rightwardsLauncher->x() + edgeDragArea->distanceThreshold() * 5.0f);
639+
640+ for (int i = 0; i < totalMovementSteps; ++i) {
641+ touchPoint += touchMovement;
642+ passTime(movementTimeStepMs);
643+ QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
644+ }
543
645
544 QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
646 QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
545− QCOMPARE(draggingSpy.count(), 1);
647+
648+ QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
649+}
650+
651+/*
652+ The presence of and old, rejected, touch point lying on the DirectionalDragArea
653+ shouldn't impede the recognition of a gesture from a new touch point.
654+ */
655+void tst_DirectionalDragArea::ignoreOldFinger()
656+{
657+ DirectionalDragArea *edgeDragArea =
658+ m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
659+ Q_ASSERT(edgeDragArea != 0);
660+ edgeDragArea->setRecognitionTimer(fakeTimer);
661+ edgeDragArea->setTimeSource(fakeTimeSource);
662+
663+ // Make touches evenly spaced along the edgeDragArea
664+ QPoint touch0Pos(edgeDragArea->width()/2.0f, m_view->height()*0.33f);
665+ QPoint touch1Pos(edgeDragArea->width()/2.0f, m_view->height()*0.66f);
666+
667+ QTest::touchEvent(m_view, m_device).press(0, touch0Pos);
668+
669+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
670+
671+ // leave it lying around for some time
672+ passTime(qMax(edgeDragArea->maxSilenceTime(), edgeDragArea->compositionTime()) * 10);
673+
674+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
675+
676+ qreal desiredDragDistance = edgeDragArea->distanceThreshold()*2.0f;
677+ QPointF dragDirectionVector(1.0f, 0.0f);
678+
679+ qreal movementStepDistance = edgeDragArea->distanceThreshold() * 0.1f;
680+ QPointF touchMovement = dragDirectionVector * movementStepDistance;
681+ int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
682+ int movementTimeStepMs = (edgeDragArea->compositionTime() * 1.5f) / totalMovementSteps;
683+
684+ QTest::touchEvent(m_view, m_device)
685+ .move(0, touch0Pos)
686+ .press(1, touch1Pos);
687+
546− QCOMPARE(edgeDragArea->dragging(), true);
688+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
689+
690+ for (int i = 0; i < totalMovementSteps; ++i) {
691+ touch1Pos += touchMovement.toPoint();
692+ passTime(movementTimeStepMs);
693+ QTest::touchEvent(m_view, m_device)
694+ .move(0, touch0Pos)
695+ .move(1, touch1Pos);
696+ }
697+
698+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
699+
700+ QTest::touchEvent(m_view, m_device)
701+ .move(0, touch0Pos)
702+ .release(1, touch1Pos);
703+
704+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
547}
705}
548
706
549QTEST_MAIN(tst_DirectionalDragArea)
707QTEST_MAIN(tst_DirectionalDragArea)
tests/plugins/Ubuntu/Gestures/edgeDragExample.qml → tests/plugins/Ubuntu/Gestures/tst_DirectionalDragArea.qmlrenamed+9−3
@@ -18,8 +18,8 @@ import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19
19
20Rectangle {
20Rectangle {
21− //width: units.gu(40)
21+ width: units.gu(40)
22− //height: units.gu(71)
22+ height: units.gu(71)
23 color: "white"
23 color: "white"
24
24
25 MouseArea {
25 MouseArea {
@@ -33,7 +33,13 @@ Rectangle {
33 }
33 }
34 }
34 }
35
35
36+ // NB: Do not anchor it as we will move it programmatically from the test
36− RightwardsLauncher { id: hpLauncher; anchors.fill: parent }
37+ RightwardsLauncher {
38+ id: hpLauncher;
39+ width: parent.width
40+ height: parent.height
41+ }
42+
37 LeftwardsLauncher { id: hnLauncher; anchors.fill: parent }
43 LeftwardsLauncher { id: hnLauncher; anchors.fill: parent }
38 DownwardsLauncher { id: vpLauncher; anchors.fill: parent }
44 DownwardsLauncher { id: vpLauncher; anchors.fill: parent }
39 UpwardsLauncher { id: vnLauncher; anchors.fill: parent }
45 UpwardsLauncher { id: vnLauncher; anchors.fill: parent }
tests/plugins/Unity/CMakeLists.txt−51
@@ -1,53 +1,2 @@
1add_subdirectory(Indicators)
1add_subdirectory(Indicators)
2add_subdirectory(Launcher)
2add_subdirectory(Launcher)
3−
4−pkg_check_modules(UNITYCORE REQUIRED unity-core-6.0>=7.1.1)
5−pkg_check_modules(LIBUNITYPROTO REQUIRED unity-protocol-private)
6−pkg_check_modules(LIBUNITY REQUIRED unity)
7−pkg_check_modules(LIBSIGCPP REQUIRED sigc++-2.0)
8−pkg_check_modules(QTDEE REQUIRED libdee-qt5>=3.2)
9−
10−include_directories(
11− ${Unity-qml_SOURCE_DIR}
12− ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/Unity
13− ${CMAKE_CURRENT_BINARY_DIR}
14− ${LIBUNITYPROTO_INCLUDE_DIRS}
15− ${LIBUNITY_INCLUDE_DIRS}
16− ${LIBSIGCPP_INCLUDE_DIRS}
17− ${UNITYCORE_INCLUDE_DIRS}
18− ${QTDEE_INCLUDE_DIRS}
19− )
20−
21−macro(run_tests)
22− set(_test_list "")
23− foreach(_test ${ARGN})
24− set(testCommand
25− ${CMAKE_CURRENT_BINARY_DIR}/${_test}Exec
26− -o ${CMAKE_BINARY_DIR}/${_test}.xml,xunitxml
27− -o -,txt)
28− add_test(NAME test${CLASSNAME}${_test} COMMAND ${testCommand})
29− add_custom_target(${_test} ${testCommand})
30− add_executable(${_test}Exec ${_test}.cpp)
31− qt5_use_modules(${_test}Exec Test Core Qml)
32− set_tests_properties(test${CLASSNAME}${_test}
33− PROPERTIES ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/plugins/Unity:${LIBUNITYPROTO_LIBRARY_DIRS}")
34−
35− target_link_libraries(${_test}Exec
36− Unity-qml
37− ${UNITYCORE_LDFLAGS}
38− ${LIBUNITY_LDFLAGS}
39− ${LIBUNITYPROTO_LDFLAGS}
40− ${LIBSIGCPP_LDFLAGS}
41− ${QTDEE_LDFLAGS}
42− )
43−
44− set(_test_list "${_test_list};${_test}")
45− endforeach()
46−endmacro(run_tests)
47−
48−run_tests(
49− signalslisttest
50− previewbindingstest
51− filtersbindingstest
52− resultstest
53− )
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)
1pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
3pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
2
4
5+set(INDICATORS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../plugins/Unity/Indicators)
6+set(TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
7+
3include_directories(
8include_directories(
4 ${CMAKE_CURRENT_BINARY_DIR}
9 ${CMAKE_CURRENT_BINARY_DIR}
5− ${CMAKE_CURRENT_SOURCE_DIR}/../../../../plugins/Unity/Indicators
10+ ${INDICATORS_DIR}
6− ${QMENUMODEL_INCLUDE_DIRS}
11+ ${TEST_DIR}/mocks/QMenuModel
12+ ${GLIB_INCLUDE_DIRS}
13+ ${GIO_INCLUDE_DIRS}
7 )
14 )
8
15
9−macro(run_tests)
16+macro(indicator_test TEST)
10− set(_test_list "")
17+ set(multi_value_keywords ADDITIONAL_CPPS ADDITIONAL_LIBS)
11− foreach(_test ${ARGN})
18+ cmake_parse_arguments(test "" "" "${multi_value_keywords}" ${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)
27
19
28−run_tests(
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+
29− indicatorsmanagertest
38+indicator_test(indicatorsmanagertest ADDITIONAL_LIBS IndicatorsQml)
30− indicatorsmodeltest
39+indicator_test(indicatorsmodeltest ADDITIONAL_LIBS IndicatorsQml)
31− menucontentactivatortest
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)
32− rootactionstatetest
42+indicator_test(rootactionstatetest ADDITIONAL_LIBS IndicatorsQml)
33− timeformattertest
43+indicator_test(timeformattertest ADDITIONAL_LIBS IndicatorsQml)
34− )
tests/plugins/Unity/Indicators/indicatorsmanagertest.cpp+1−3
@@ -80,9 +80,7 @@ private Q_SLOTS:
80 QCOMPARE(props["busName"].toString(), QString("com.canonical.indicator.fake1"));
80 QCOMPARE(props["busName"].toString(), QString("com.canonical.indicator.fake1"));
81 QCOMPARE(props["actionsObjectPath"].toString(), QString("/com/canonical/indicator/fake1"));
81 QCOMPARE(props["actionsObjectPath"].toString(), QString("/com/canonical/indicator/fake1"));
82
82
83− QVariantMap objectPaths = props["menuObjectPaths"].toMap();
84− QCOMPARE(objectPaths["phone"].toString(), QString("/com/canonical/indicator/fake1/phone"));
83+ QCOMPARE(props["menuObjectPath"].toString(), QString("/com/canonical/indicator/fake1/phone"));
85− QCOMPARE(objectPaths["desktop"].toString(), QString("/com/canonical/indicator/fake1/desktop"));
86 }
84 }
87
85
88 /*
86 /*
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/filtersbindingstest.cppdeleted−515
@@ -1,515 +0,0 @@
1−/*
2−* Copyright (C) 2013 Canonical, Ltd.
3−*
4−* Authors:
5−* Pawel Stolowski <pawel.stolowski@canonical.com>
6−*
7−* This program is free software; you can redistribute it and/or modify
8−* it under the terms of the GNU General Public License as published by
9−* the Free Software Foundation; version 3.
10−*
11−* This program is distributed in the hope that it will be useful,
12−* but WITHOUT ANY WARRANTY; without even the implied warranty of
13−* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14−* GNU General Public License for more details.
15−*
16−* You should have received a copy of the GNU General Public License
17−* along with this program. If not, see <http://www.gnu.org/licenses/>.
18−*/
19−
20−#include "filtersbindingstest.h"
21−
22−// libunity-core
23−#include <UnityCore/Filter.h>
24−#include <UnityCore/MultiRangeFilter.h>
25−
26−// Qt
27−#include <QTest>
28−#include <QSignalSpy>
29−
30−// libunity
31−#include <unity.h>
32−
33−// local
34−#include "filter.h"
35−#include "multirangefilter.h"
36−#include "checkoptionfilter.h"
37−#include "radiooptionfilter.h"
38−#include "ratingsfilter.h"
39−#include "ratingfilteroption.h"
40−#include "genericoptionsmodel.h"
41−
42−void FiltersBindingsTest::initTestCase()
43−{
44−}
45−
46−GVariant* FiltersBindingsTest::createOptions(int numOfOptions)
47−{
48− auto vtype = g_variant_type_new("a(sssb)");
49− auto vb = g_variant_builder_new(vtype);
50− for (int i = 0; i<numOfOptions; i++) {
51− const std::string optId = "opt" + std::to_string(i);
52− const std::string optName = "Option " + std::to_string(i);
53− g_variant_builder_add(vb, "(sssb)", optId.c_str(), optName.c_str(), "", false);
54− }
55− return g_variant_builder_end(vb);
56−}
57−
58−DeeModel* FiltersBindingsTest::createFilterModel()
59−{
60− const char* filter_schema[8] = {"s", "s", "s", "s", "a{sv}", "b", "b", "b"};
61− auto model = dee_sequence_model_new();
62− dee_model_set_schema_full (DEE_MODEL(model), filter_schema, 8);
63− return model;
64−}
65−
66−void FiltersBindingsTest::createMultiRangeFilter(DeeModel *model, const std::string &id, const std::string &name, int optionCount)
67−{
68− createFilter(model, "filter-multirange", id, name, optionCount, true);
69−}
70−
71−void FiltersBindingsTest::createRadioOptionFilter(DeeModel *model, const std::string &id, const std::string &name, int optionCount)
72−{
73− createFilter(model, "filter-radiooption", id, name, optionCount, true);
74−}
75−
76−void FiltersBindingsTest::createCheckOptionFilter(DeeModel *model, const std::string &id, const std::string &name, int optionCount)
77−{
78− createFilter(model, "filter-checkoption", id, name, optionCount, true);
79−}
80−
81−void FiltersBindingsTest::createRatingsFilter(DeeModel *model, const std::string &id, const std::string &name)
82−{
83− GVariant* row[8];
84−
85− row[0] = g_variant_new_string(id.c_str());
86− row[1] = g_variant_new_string(name.c_str());
87− row[2] = g_variant_new_string(""); // icon hint
88− row[3] = g_variant_new_string("filter-ratings");
89−
90− GVariant *children[2];
91− GVariant *key1 = g_variant_new_string("show-all-button");
92− GVariant *key2 = g_variant_new_string("rating");
93− children[0] = g_variant_new_dict_entry(key1, g_variant_new_variant(g_variant_new_boolean(true)));
94− children[1] = g_variant_new_dict_entry(key2, g_variant_new_variant(g_variant_new_double(0.0f)));
95− auto fhints = g_variant_new_array(G_VARIANT_TYPE("{sv}"), children, 2);
96−
97− row[4] = fhints;
98− row[5] = g_variant_new_boolean(true); // visible
99− row[6] = g_variant_new_boolean(false); // collapsed
100− row[7] = g_variant_new_boolean(false); // filtering
101−
102− dee_model_append_row(model, row);
103−}
104−
105−void FiltersBindingsTest::createFilter(DeeModel *model, const std::string &renderer, const std::string &id, const std::string &name, int optionCount, bool showAll)
106−{
107− GVariant* row[8];
108−
109− row[0] = g_variant_new_string(id.c_str());
110− row[1] = g_variant_new_string(name.c_str());
111− row[2] = g_variant_new_string(""); // icon hint
112− row[3] = g_variant_new_string(renderer.c_str()); // renderer
113−
114− GVariant *children[2];
115− GVariant *key1 = g_variant_new_string("show-all-button");
116− GVariant *key2 = g_variant_new_string("options");
117− children[0] = g_variant_new_dict_entry(key1, g_variant_new_variant(g_variant_new_boolean(showAll)));
118− children[1] = g_variant_new_dict_entry(key2, g_variant_new_variant(createOptions(optionCount)));
119− auto fhints = g_variant_new_array(G_VARIANT_TYPE("{sv}"), children, 2);
120−
121− row[4] = fhints;
122− row[5] = g_variant_new_boolean(true); // visible
123− row[6] = g_variant_new_boolean(false); // collapsed
124− row[7] = g_variant_new_boolean(false); // filtering
125−
126− dee_model_append_row(model, row);
127−}
128−
129−void FiltersBindingsTest::testMultiRangeFilter()
130−{
131− auto model = createFilterModel();
132−
133− createMultiRangeFilter(model, "f1", "Filter1", 1);
134− createMultiRangeFilter(model, "f2", "Filter2", 2);
135− createMultiRangeFilter(model, "f3", "Filter3", 3);
136−
137− // create filter out of 1st row
138− auto iter = dee_model_get_first_iter(DEE_MODEL(model));
139− {
140− auto core_filter = unity::dash::Filter::FilterFromIter(model, iter);
141− QVERIFY(core_filter != nullptr);
142− auto bind_filter = Filter::newFromUnityFilter(core_filter);
143− auto multi_filter = dynamic_cast<MultiRangeFilter*>(bind_filter);
144− QVERIFY(multi_filter != nullptr);
145− auto options = multi_filter->options();
146− QCOMPARE(options->rowCount(), 2);
147−
148− auto idx = options->index(1);
149− QVariant id_var = options->data(idx, GenericOptionsModel::RoleId);
150− QVariant name_var = options->data(idx, GenericOptionsModel::RoleName);
151− QVariant icon_var = options->data(idx, GenericOptionsModel::RoleIconHint);
152− QVariant active_var = options->data(idx, GenericOptionsModel::RoleActive);
153−
154− QCOMPARE(id_var.toString(), QString("opt0"));
155− QCOMPARE(name_var.toString(), QString("Option 0"));
156− QCOMPARE(icon_var.toString(), QString(""));
157− QCOMPARE(active_var.toBool(), false);
158−
159− delete multi_filter;
160− }
161−
162− // create filter out of 2nd row
163− iter = dee_model_next(DEE_MODEL(model), iter);
164− {
165− auto core_filter = unity::dash::Filter::FilterFromIter(model, iter);
166− QVERIFY(core_filter != nullptr);
167− auto bind_filter = Filter::newFromUnityFilter(core_filter);
168− auto multi_filter = dynamic_cast<MultiRangeFilter*>(bind_filter);
169− QVERIFY(multi_filter != nullptr);
170− auto options = multi_filter->options();
171− QCOMPARE(options->rowCount(), 3);
172−
173− auto idx = options->index(1);
174− QVariant id_var = options->data(idx, GenericOptionsModel::RoleId);
175− QVariant name_var = options->data(idx, GenericOptionsModel::RoleName);
176− QVariant icon_var = options->data(idx, GenericOptionsModel::RoleIconHint);
177− QVariant active_var = options->data(idx, GenericOptionsModel::RoleActive);
178−
179− QCOMPARE(id_var.toString(), QString("opt0"));
180− QCOMPARE(name_var.toString(), QString("Option 0"));
181− QCOMPARE(icon_var.toString(), QString(""));
182− QCOMPARE(active_var.toBool(), false);
183−
184− AbstractFilterOption* opt1 = options->getRawOption(1);
185− QCOMPARE(opt1->id(), QString("opt0"));
186−
187− AbstractFilterOption* opt2 = options->getRawOption(2);
188− QCOMPARE(opt2->id(), QString("opt1"));
189−
190− delete multi_filter;
191− }
192−
193− // create filter out of 3nd row
194− iter = dee_model_next(DEE_MODEL(model), iter);
195− {
196− auto core_filter = unity::dash::Filter::FilterFromIter(model, iter);
197− QVERIFY(core_filter != nullptr);
198− auto bind_filter = Filter::newFromUnityFilter(core_filter);
199− auto multi_filter = dynamic_cast<MultiRangeFilter*>(bind_filter);
200− QVERIFY(multi_filter != nullptr);
201− auto options = multi_filter->options();
202− QCOMPARE(options->rowCount(), 4);
203−
204− AbstractFilterOption* showAll = options->getRawOption(0);
205− QVERIFY(showAll->id().startsWith("show_all::"));
206−
207− AbstractFilterOption* opt0 = options->getRawOption(1);
208− QCOMPARE(opt0->id(), QString("opt0"));
209−
210− AbstractFilterOption* opt1 = options->getRawOption(2);
211− QCOMPARE(opt1->id(), QString("opt1"));
212−
213− AbstractFilterOption* opt2 = options->getRawOption(3);
214− QCOMPARE(opt2->id(), QString("opt2"));
215−
216− // verify filter options are bound to correct underlying unity options
217− auto core_multi_filter = std::dynamic_pointer_cast<unity::dash::MultiRangeFilter>(core_filter);
218− QCOMPARE(QString::fromStdString(core_multi_filter->options()[0]->id()), QString("opt0"));
219− QCOMPARE(QString::fromStdString(core_multi_filter->options()[1]->id()), QString("opt1"));
220− QCOMPARE(QString::fromStdString(core_multi_filter->options()[2]->id()), QString("opt2"));
221−
222− QSignalSpy opt0spy(opt0, SIGNAL(activeChanged(bool)));
223− QSignalSpy opt1spy(opt1, SIGNAL(activeChanged(bool)));
224− QSignalSpy opt2spy(opt2, SIGNAL(activeChanged(bool)));
225−
226− // test active property changes
227− QCOMPARE(opt0->active(), false);
228−
229− opt0->setActive(true); // activate 1st option
230− QCOMPARE(opt0spy.count(), 1);
231− QCOMPARE(opt1spy.count(), 0);
232− QCOMPARE(opt2spy.count(), 0);
233− QCOMPARE(opt0->active(), true);
234− QCOMPARE(opt1->active(), false);
235− QCOMPARE(opt2->active(), false);
236−
237− opt1->setActive(true);
238− QCOMPARE(opt0spy.count(), 2);
239− QCOMPARE(opt1spy.count(), 1);
240− QCOMPARE(opt2spy.count(), 0);
241− QCOMPARE(opt0->active(), false); //1st combined option gets deactivated
242− QCOMPARE(opt1->active(), true);
243− QCOMPARE(opt2->active(), false);
244−
245− opt1->setActive(false); // and de-activate it
246− QCOMPARE(opt0spy.count(), 2);
247− QCOMPARE(opt1spy.count(), 2);
248− QCOMPARE(opt2spy.count(), 0);
249− QCOMPARE(opt0->active(), false);
250− QCOMPARE(opt1->active(), false);
251− QCOMPARE(opt2->active(), false);
252−
253− opt2->setActive(true); // activate another combined option
254− QCOMPARE(opt0spy.count(), 2);
255− QCOMPARE(opt1spy.count(), 2);
256− QCOMPARE(opt2spy.count(), 1);
257− QCOMPARE(opt0->active(), false);
258− QCOMPARE(opt1->active(), false);
259− QCOMPARE(opt2->active(), true);
260−
261− delete multi_filter;
262− }
263−}
264−
265−void FiltersBindingsTest::testCheckOptionFilter()
266−{
267− auto model = createFilterModel();
268−
269− createCheckOptionFilter(model, "f1", "Filter1", 3);
270−
271− // create filter out of 1st row
272− auto iter = dee_model_get_first_iter(DEE_MODEL(model));
273− {
274− auto core_filter = unity::dash::Filter::FilterFromIter(model, iter);
275− QVERIFY(core_filter != nullptr);
276− auto bind_filter = Filter::newFromUnityFilter(core_filter);
277− auto check_filter = dynamic_cast<CheckOptionFilter*>(bind_filter);
278− QVERIFY(check_filter != nullptr);
279− auto options = check_filter->options();
280− QCOMPARE(options->rowCount(), 4);
281−
282− QCOMPARE(check_filter->id(), QString("f1"));
283− QCOMPARE(check_filter->name(), QString("Filter1"));
284− QCOMPARE(check_filter->iconHint(), QString(""));
285− QCOMPARE(check_filter->rendererName(), QString("filter-checkoption"));
286− QCOMPARE(check_filter->visible(), true);
287− QCOMPARE(check_filter->collapsed(), false);
288− QCOMPARE(check_filter->filtering(), false);
289−
290− auto idx = options->index(1);
291− QVariant id_var = options->data(idx, GenericOptionsModel::RoleId);
292− QVariant name_var = options->data(idx, GenericOptionsModel::RoleName);
293− QVariant icon_var = options->data(idx, GenericOptionsModel::RoleIconHint);
294− QVariant active_var = options->data(idx, GenericOptionsModel::RoleActive);
295−
296− QCOMPARE(id_var.toString(), QString("opt0"));
297− QCOMPARE(name_var.toString(), QString("Option 0"));
298− QCOMPARE(icon_var.toString(), QString(""));
299− QCOMPARE(active_var.toBool(), false);
300−
301− idx = options->index(2);
302− id_var = options->data(idx, GenericOptionsModel::RoleId);
303− name_var = options->data(idx, GenericOptionsModel::RoleName);
304− icon_var = options->data(idx, GenericOptionsModel::RoleIconHint);
305− active_var = options->data(idx, GenericOptionsModel::RoleActive);
306−
307− QCOMPARE(id_var.toString(), QString("opt1"));
308− QCOMPARE(name_var.toString(), QString("Option 1"));
309− QCOMPARE(icon_var.toString(), QString(""));
310− QCOMPARE(active_var.toBool(), false);
311−
312− AbstractFilterOption* showAll = options->getRawOption(0);
313− AbstractFilterOption* opt0 = options->getRawOption(1);
314− AbstractFilterOption* opt1 = options->getRawOption(2);
315− AbstractFilterOption* opt2 = options->getRawOption(3);
316−
317− QSignalSpy showAllSpy(showAll, SIGNAL(activeChanged(bool)));
318− QSignalSpy opt0spy(opt0, SIGNAL(activeChanged(bool)));
319− QSignalSpy opt1spy(opt1, SIGNAL(activeChanged(bool)));
320− QSignalSpy opt2spy(opt2, SIGNAL(activeChanged(bool)));
321− QSignalSpy dataChangedSpy(options, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)));
322−
323− // test active property changes
324− QCOMPARE(showAll->active(), false);
325− QCOMPARE(opt0->active(), false);
326− QCOMPARE(opt1->active(), false);
327− QCOMPARE(opt2->active(), false);
328−
329− opt0->setActive(true);
330− QCOMPARE(showAllSpy.count(), 0);
331− QCOMPARE(opt0spy.count(), 1);
332− QCOMPARE(opt1spy.count(), 0);
333− QCOMPARE(opt2spy.count(), 0);
334− QCOMPARE(showAll->active(), false);
335− QCOMPARE(opt0->active(), true);
336− QCOMPARE(opt1->active(), false);
337− QCOMPARE(opt2->active(), false);
338−
339− opt1->setActive(true);
340− QCOMPARE(showAllSpy.count(), 0);
341− QCOMPARE(opt0spy.count(), 2);
342− QCOMPARE(opt1spy.count(), 1);
343− QCOMPARE(opt2spy.count(), 0);
344− QCOMPARE(showAll->active(), false);
345− QCOMPARE(opt0->active(), false);
346− QCOMPARE(opt1->active(), true);
347− QCOMPARE(opt2->active(), false);
348−
349− QCOMPARE(dataChangedSpy.count(), 3);
350−
351− showAll->setActive(true);
352− QCOMPARE(showAllSpy.count(), 1);
353− QCOMPARE(opt0spy.count(), 2);
354− QCOMPARE(opt1spy.count(), 2);
355− QCOMPARE(opt2spy.count(), 0);
356− QCOMPARE(showAll->active(), true);
357− QCOMPARE(opt0->active(), false);
358− QCOMPARE(opt1->active(), false);
359− QCOMPARE(opt2->active(), false);
360−
361− delete check_filter;
362− }
363−}
364−
365−void FiltersBindingsTest::testRadioOptionFilter()
366−{
367− auto model = createFilterModel();
368−
369− createRadioOptionFilter(model, "f1", "Filter1", 3);
370−
371− // create filter out of 1st row
372− auto iter = dee_model_get_first_iter(DEE_MODEL(model));
373− {
374− auto core_filter = unity::dash::Filter::FilterFromIter(model, iter);
375− QVERIFY(core_filter != nullptr);
376− auto bind_filter = Filter::newFromUnityFilter(core_filter);
377− auto radio_filter = dynamic_cast<RadioOptionFilter*>(bind_filter);
378− QVERIFY(radio_filter != nullptr);
379− auto options = radio_filter->options();
380− QCOMPARE(options->rowCount(), 4);
381−
382− auto idx = options->index(0);
383− QVariant id_var = options->data(idx, GenericOptionsModel::RoleId);
384− QVariant name_var = options->data(idx, GenericOptionsModel::RoleName);
385− QVariant icon_var = options->data(idx, GenericOptionsModel::RoleIconHint);
386− QVariant active_var = options->data(idx, GenericOptionsModel::RoleActive);
387−
388− QVERIFY(id_var.toString().startsWith("show_all::"));
389− QVERIFY(name_var.toString().size() > 0);
390− QCOMPARE(icon_var.toString(), QString(""));
391− QCOMPARE(active_var.toBool(), false);
392−
393− idx = options->index(1);
394− id_var = options->data(idx, GenericOptionsModel::RoleId);
395− name_var = options->data(idx, GenericOptionsModel::RoleName);
396− icon_var = options->data(idx, GenericOptionsModel::RoleIconHint);
397− active_var = options->data(idx, GenericOptionsModel::RoleActive);
398−
399− QCOMPARE(id_var.toString(), QString("opt0"));
400− QCOMPARE(name_var.toString(), QString("Option 0"));
401− QCOMPARE(icon_var.toString(), QString(""));
402− QCOMPARE(active_var.toBool(), false);
403−
404− idx = options->index(2);
405− id_var = options->data(idx, GenericOptionsModel::RoleId);
406− name_var = options->data(idx, GenericOptionsModel::RoleName);
407− icon_var = options->data(idx, GenericOptionsModel::RoleIconHint);
408− active_var = options->data(idx, GenericOptionsModel::RoleActive);
409−
410− QCOMPARE(id_var.toString(), QString("opt1"));
411− QCOMPARE(name_var.toString(), QString("Option 1"));
412− QCOMPARE(icon_var.toString(), QString(""));
413− QCOMPARE(active_var.toBool(), false);
414−
415− AbstractFilterOption* opt0 = options->getRawOption(1);
416− AbstractFilterOption* opt1 = options->getRawOption(2);
417− AbstractFilterOption* opt2 = options->getRawOption(3);
418−
419− QSignalSpy opt0spy(opt0, SIGNAL(activeChanged(bool)));
420− QSignalSpy opt1spy(opt1, SIGNAL(activeChanged(bool)));
421− QSignalSpy opt2spy(opt2, SIGNAL(activeChanged(bool)));
422− QSignalSpy dataChangedSpy(options, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)));
423−
424− // test active property changes
425− QCOMPARE(opt0->active(), false);
426− QCOMPARE(opt1->active(), false);
427− QCOMPARE(opt2->active(), false);
428−
429− opt0->setActive(true);
430− QCOMPARE(opt0spy.count(), 1);
431− QCOMPARE(opt1spy.count(), 0);
432− QCOMPARE(opt2spy.count(), 0);
433− QCOMPARE(opt0->active(), true);
434− QCOMPARE(opt1->active(), false);
435− QCOMPARE(opt2->active(), false);
436−
437− opt1->setActive(true);
438− QCOMPARE(opt0spy.count(), 2);
439− QCOMPARE(opt1spy.count(), 1);
440− QCOMPARE(opt2spy.count(), 0);
441− QCOMPARE(opt0->active(), false);
442− QCOMPARE(opt1->active(), true);
443− QCOMPARE(opt2->active(), false);
444−
445− QCOMPARE(dataChangedSpy.count(), 3);
446−
447− delete radio_filter;
448− }
449−}
450−
451−void FiltersBindingsTest::testRatingsFilter()
452−{
453− auto model = createFilterModel();
454−
455− createRatingsFilter(model, "f1", "Filter1");
456−
457− // create filter out of 1st row
458− auto iter = dee_model_get_first_iter(DEE_MODEL(model));
459− {
460− auto core_filter = unity::dash::Filter::FilterFromIter(model, iter);
461− QVERIFY(core_filter != nullptr);
462− auto bind_filter = Filter::newFromUnityFilter(core_filter);
463− auto rating_filter = dynamic_cast<RatingsFilter*>(bind_filter);
464− QVERIFY(rating_filter != nullptr);
465− auto options = rating_filter->options();
466− QCOMPARE(options->rowCount(), 6);
467−
468− RatingFilterOption* opt[5];
469− for (int i = 0; i<5; i++) {
470− opt[i] = dynamic_cast<RatingFilterOption *>(options->getRawOption(i+1));
471− }
472−
473− QSignalSpy opt0spy(opt[0], SIGNAL(activeChanged(bool)));
474− QSignalSpy opt4spy(opt[4], SIGNAL(activeChanged(bool)));
475− QSignalSpy dataChangedSpy(options, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)));
476−
477− QVERIFY(qAbs(opt[0]->value() - 0.2f) <= 0.0001f);
478− QVERIFY(qAbs(opt[1]->value() - 0.4f) <= 0.0001f);
479− QVERIFY(qAbs(opt[2]->value() - 0.6f) <= 0.0001f);
480− QVERIFY(qAbs(opt[3]->value() - 0.8f) <= 0.0001f);
481− QVERIFY(qAbs(opt[4]->value() - 1.0f) <= 0.0001f);
482−
483− QVERIFY(rating_filter->rating() <= 0.0001f); // rating equals zero
484−
485− // all options initially inactive
486− for (int i=0; i<5; i++) {
487− QCOMPARE(opt[i]->active(), false);
488− }
489−
490− // verify activation for all options
491− for (int i=0; i<5; i++) {
492− opt[i]->setActive(true);
493− QCOMPARE(opt[i]->active(), true);
494− QVERIFY(rating_filter->rating() - ((i+1)*0.2f) <= 0.0001f);
495−
496− // verify that all other options are inactive
497− for (int j=0; j<5; j++) {
498− if (i != j) {
499− QCOMPARE(opt[j]->active(), false);
500− }
501− }
502− }
503−
504− QCOMPARE(opt0spy.count(), 2);
505− QCOMPARE(opt4spy.count(), 1);
506−
507− opt[4]->setActive(false);
508− QVERIFY(rating_filter->rating() <= 0.0001f); // rating equals zero
509− QCOMPARE(opt4spy.count(), 2);
510−
511− QCOMPARE(dataChangedSpy.count(), 10);
512− }
513−}
514−
515−QTEST_MAIN(FiltersBindingsTest)
tests/plugins/Unity/filtersbindingstest.hdeleted−47
@@ -1,47 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * Authors:
5− * Pawel Stolowski <pawel.stolowski@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#ifndef FILTERSBINDINGSTEST_H
21−#define FILTERSBINDINGSTEST_H
22−
23−#include <QObject>
24−#include <dee.h>
25−
26−class FiltersBindingsTest : public QObject
27−{
28− Q_OBJECT
29−
30− private Q_SLOTS:
31− void initTestCase();
32− void testMultiRangeFilter();
33− void testCheckOptionFilter();
34− void testRadioOptionFilter();
35− void testRatingsFilter();
36−
37− private:
38− DeeModel* createFilterModel();
39− GVariant* createOptions(int numOfOptions);
40− void createMultiRangeFilter(DeeModel *model, const std::string &id, const std::string &name, int optionCount);
41− void createCheckOptionFilter(DeeModel *model, const std::string &id, const std::string &name, int optionCount);
42− void createRadioOptionFilter(DeeModel *model, const std::string &id, const std::string &name, int optionCount);
43− void createRatingsFilter(DeeModel *model, const std::string &id, const std::string &name);
44− void createFilter(DeeModel *model, const std::string &renderer, const std::string &id, const std::string &name, int optionCount, bool showAll);
45−};
46−
47−#endif // FILTERSBINDINGSTEST_H
tests/plugins/Unity/previewbindingstest.cppdeleted−194
@@ -1,194 +0,0 @@
1−/*
2− * Copyright (C) 2011, 2013 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−#include "previewbindingstest.h"
18−#include <QTest>
19−
20−#include <UnityCore/Preview.h>
21−#include <UnityCore/GLibWrapper.h>
22−#include <UnityCore/Variant.h>
23−#include <unity-protocol.h>
24−
25−#include "genericpreview.h"
26−#include "applicationpreview.h"
27−#include "moviepreview.h"
28−#include "musicpreview.h"
29−#include "socialpreview.h"
30−#include "socialpreviewcomment.h"
31−#include "previewaction.h"
32−
33−#include <glib.h>
34−#include <glib-object.h>
35−
36−void PreviewBindingsTest::initTestCase()
37−{
38−}
39−
40−void PreviewBindingsTest::testGenericPreview()
41−{
42− auto rawPreview = (GObject *)unity_protocol_generic_preview_new();
43− unity_protocol_preview_set_title(UNITY_PROTOCOL_PREVIEW(rawPreview), "Metallica");
44− unity_protocol_preview_set_subtitle(UNITY_PROTOCOL_PREVIEW(rawPreview), "Ride The Lightning");
45− unity_protocol_preview_set_description(UNITY_PROTOCOL_PREVIEW(rawPreview), "Lorem ipsum dolor sit amet");
46− GFile *iconFile = g_file_new_for_path("/foo.png");
47− GIcon *icon = g_file_icon_new(iconFile);
48− unity_protocol_preview_add_action(UNITY_PROTOCOL_PREVIEW(rawPreview), "1", "Action1", icon,
49− UNITY_PROTOCOL_LAYOUT_HINT_LEFT);
50− unity::glib::Object<GObject> genPrv(rawPreview);
51−
52− // create local result
53− unity::glib::HintsMap hints;
54− hints["a"] = unity::glib::Variant(g_variant_new_string("b"));
55− unity::dash::LocalResult localResult;
56− localResult.uri = "http://foo";
57− localResult.icon_hint = "xyz";
58− localResult.category_index = 1;
59− localResult.result_type = 2;
60− localResult.mimetype = "abc";
61− localResult.name = "baz";
62− localResult.comment = "qwerty";
63− localResult.dnd_uri = "zzz";
64− localResult.hints = hints;
65−
66− auto corePrv = unity::dash::Preview::PreviewForProtocolObject(genPrv);
67− corePrv->preview_result = localResult;
68−
69− auto prv = Preview::newFromUnityPreview(corePrv);
70−
71− QCOMPARE(prv != nullptr, true);
72− QCOMPARE(prv->title(), QString("Metallica"));
73− QCOMPARE(prv->subtitle(), QString("Ride The Lightning"));
74− QCOMPARE(prv->description(), QString("Lorem ipsum dolor sit amet"));
75−
76− auto actions = prv->actions().value<QList<QObject *>>();
77− QCOMPARE(actions.size(), 1);
78− auto act = dynamic_cast<PreviewAction *>(actions[0]);
79− QVERIFY(act != nullptr);
80− QCOMPARE(act->id(), QString("1"));
81− QCOMPARE(act->displayName(), QString("Action1"));
82− QCOMPARE(act->iconHint(), QString("/foo.png"));
83−
84− Result* res = prv->result().value<Result*>();
85− QCOMPARE(res->uri(), QString("http://foo"));
86− QCOMPARE(res->iconHint(), QString("xyz"));
87− QCOMPARE(res->categoryIndex(), 1u);
88− QCOMPARE(res->resultType(), 2u);
89− QCOMPARE(res->mimeType(), QString("abc"));
90− QCOMPARE(res->title(), QString("baz"));
91− QCOMPARE(res->dndUri(), QString("zzz"));
92− QCOMPARE(res->metadata().toHash()["a"].toString(), QString("b"));
93−
94− g_object_unref(icon);
95− g_object_unref(iconFile);
96−}
97−
98−void PreviewBindingsTest::testApplicationPreview()
99−{
100− auto rawPreview = (GObject *)unity_protocol_application_preview_new();
101− unity_protocol_preview_set_title(UNITY_PROTOCOL_PREVIEW(rawPreview), "Firefox");
102− unity_protocol_preview_set_subtitle(UNITY_PROTOCOL_PREVIEW(rawPreview), "Web Browser");
103− unity_protocol_preview_set_description(UNITY_PROTOCOL_PREVIEW(rawPreview), "Lorem ipsum dolor sit amet");
104− unity_protocol_application_preview_set_license(UNITY_PROTOCOL_APPLICATION_PREVIEW(rawPreview), "GPL");
105− unity_protocol_application_preview_set_rating(UNITY_PROTOCOL_APPLICATION_PREVIEW(rawPreview), 0.5f);
106− unity_protocol_application_preview_set_num_ratings(UNITY_PROTOCOL_APPLICATION_PREVIEW(rawPreview), 4);
107− unity::glib::Object<GObject> genPrv(rawPreview);
108−
109− auto corePrv = unity::dash::Preview::PreviewForProtocolObject(genPrv);
110− auto prv = Preview::newFromUnityPreview(corePrv);
111− auto appPrv = dynamic_cast<ApplicationPreview*>(prv);
112−
113− QCOMPARE(appPrv != nullptr, true);
114− QCOMPARE(appPrv->title(), QString("Firefox"));
115− QCOMPARE(appPrv->subtitle(), QString("Web Browser"));
116− QCOMPARE(appPrv->description(), QString("Lorem ipsum dolor sit amet"));
117− QCOMPARE(appPrv->license(), QString("GPL"));
118− QCOMPARE(appPrv->rating(), 0.5f);
119− QCOMPARE(appPrv->numRatings(), unsigned (4));
120−}
121−
122−void PreviewBindingsTest::testMoviePreview()
123−{
124− auto rawPreview = (GObject *)unity_protocol_movie_preview_new();
125− unity_protocol_preview_set_title(UNITY_PROTOCOL_PREVIEW(rawPreview), "Blade Runner");
126− unity_protocol_preview_set_subtitle(UNITY_PROTOCOL_PREVIEW(rawPreview), "Ridley Scott");
127− unity_protocol_preview_set_description(UNITY_PROTOCOL_PREVIEW(rawPreview), "Lorem ipsum dolor sit amet");
128− unity_protocol_movie_preview_set_year(UNITY_PROTOCOL_MOVIE_PREVIEW(rawPreview), "1982");
129− unity::glib::Object<GObject> genPrv(rawPreview);
130−
131− auto corePrv = unity::dash::Preview::PreviewForProtocolObject(genPrv);
132− auto prv = Preview::newFromUnityPreview(corePrv);
133− auto moviePrv = dynamic_cast<MoviePreview*>(prv);
134−
135− QCOMPARE(moviePrv != nullptr, true);
136− QCOMPARE(moviePrv->title(), QString("Blade Runner"));
137− QCOMPARE(moviePrv->subtitle(), QString("Ridley Scott"));
138− QCOMPARE(moviePrv->description(), QString("Lorem ipsum dolor sit amet"));
139− QCOMPARE(moviePrv->year(), QString("1982"));
140−}
141−
142−void PreviewBindingsTest::testMusicPreview()
143−{
144− auto rawPreview = (GObject *)unity_protocol_music_preview_new();
145− unity_protocol_preview_set_title(UNITY_PROTOCOL_PREVIEW(rawPreview), "Metallica");
146− unity_protocol_preview_set_subtitle(UNITY_PROTOCOL_PREVIEW(rawPreview), "Death Magnetic");
147− unity_protocol_preview_set_description(UNITY_PROTOCOL_PREVIEW(rawPreview), "Lorem ipsum dolor sit amet");
148− unity::glib::Object<GObject> genPrv(rawPreview);
149−
150− auto corePrv = unity::dash::Preview::PreviewForProtocolObject(genPrv);
151− auto prv = Preview::newFromUnityPreview(corePrv);
152− auto musicPrv = dynamic_cast<MusicPreview*>(prv);
153−
154− QCOMPARE(musicPrv != nullptr, true);
155− QCOMPARE(musicPrv->title(), QString("Metallica"));
156− QCOMPARE(musicPrv->subtitle(), QString("Death Magnetic"));
157− QCOMPARE(musicPrv->description(), QString("Lorem ipsum dolor sit amet"));
158−}
159−
160−void PreviewBindingsTest::testSocialPreview()
161−{
162− GFile *iconFile = g_file_new_for_path("/foo.png");
163− GIcon *icon = g_file_icon_new(iconFile);
164−
165− auto rawPreview = (GObject *)unity_protocol_social_preview_new();
166− unity_protocol_social_preview_set_sender(UNITY_PROTOCOL_SOCIAL_PREVIEW(rawPreview), "John");
167− unity_protocol_social_preview_set_avatar(UNITY_PROTOCOL_SOCIAL_PREVIEW(rawPreview), icon);
168− unity_protocol_social_preview_set_content(UNITY_PROTOCOL_SOCIAL_PREVIEW(rawPreview), "Lorem ipsum dolor sit amet");
169− unity_protocol_social_preview_add_comment(UNITY_PROTOCOL_SOCIAL_PREVIEW(rawPreview), "1", "comment1", "Ubuntu", "2013-07-04 14:10");
170− unity::glib::Object<GObject> genPrv(rawPreview);
171−
172− auto corePrv = unity::dash::Preview::PreviewForProtocolObject(genPrv);
173− auto prv = Preview::newFromUnityPreview(corePrv);
174− auto socialPrv = dynamic_cast<SocialPreview*>(prv);
175−
176− QCOMPARE(socialPrv != nullptr, true);
177− QCOMPARE(socialPrv->sender(), QString("John"));
178− QCOMPARE(socialPrv->content(), QString("Lorem ipsum dolor sit amet"));
179− QCOMPARE(socialPrv->avatar(), QString("/foo.png"));
180−
181− auto comments = socialPrv->comments().value<QList<QObject *>>();
182− QCOMPARE(comments.size(), 1);
183− auto cmt = dynamic_cast<SocialPreviewComment *>(comments[0]);
184− QVERIFY(cmt != nullptr);
185− QCOMPARE(cmt->id(), QString("1"));
186− QCOMPARE(cmt->displayName(), QString("comment1"));
187− QCOMPARE(cmt->content(), QString("Ubuntu"));
188− QCOMPARE(cmt->time(), QString("2013-07-04 14:10"));
189−
190− g_object_unref(icon);
191− g_object_unref(iconFile);
192−}
193−
194−QTEST_MAIN(PreviewBindingsTest)
tests/plugins/Unity/previewbindingstest.hdeleted−35
@@ -1,35 +0,0 @@
1−/*
2− * Copyright (C) 2011, 2013 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−#ifndef PREVIEWBINDINGSTEST_H
18−#define PREVIEWBINDINGSTEST_H
19−
20−#include <QObject>
21−
22−class PreviewBindingsTest : public QObject
23−{
24− Q_OBJECT
25−
26− private Q_SLOTS:
27− void initTestCase();
28− void testGenericPreview();
29− void testApplicationPreview();
30− void testMoviePreview();
31− void testMusicPreview();
32− void testSocialPreview();
33−};
34−
35−#endif
tests/plugins/Unity/resultstest.cppdeleted−248
@@ -1,248 +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− * Authors:
17− * Michal Hruby <michal.hruby@canonical.com>
18− */
19−
20−#include <QTest>
21−#include <dee.h>
22−#include <glib.h>
23−
24−#include "resultstest.h"
25−#include "categoryresults.h"
26−#include "variantutils.h"
27−
28−static DeeModel* createBackendModel()
29−{
30− auto model = dee_sequence_model_new();
31− dee_model_set_schema(model, "s", "s", "u", "u", "s", "s", "s", "s", "a{sv}", NULL);
32−
33− return model;
34−}
35−
36−void ResultsTest::testAllColumns()
37−{
38− auto deeModel = createBackendModel();
39− GVariantBuilder builder;
40− g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
41− g_variant_builder_add(&builder, "{sv}", "metadata-field", g_variant_new_string("foo"));
42− dee_model_append (deeModel,
43− "test:uri",
44− "themed-icon",
45− 4,
46− 0,
47− "application/octet-stream",
48− "Test",
49− "Comment",
50− "test:dnd-uri",
51− g_variant_builder_end(&builder));
52−
53− CategoryResults* results = new CategoryResults(this);
54− results->setModel(deeModel);
55−
56− auto index = results->index(0, 0); // there's just one result
57− QCOMPARE(index.data(CategoryResults::Roles::RoleUri).toString(), QString("test:uri"));
58− QCOMPARE(index.data(CategoryResults::Roles::RoleIconHint).toString(), QString("image://theme/themed-icon"));
59− QCOMPARE(index.data(CategoryResults::Roles::RoleCategory).toInt(), 4);
60− QCOMPARE(index.data(CategoryResults::Roles::RoleMimetype).toString(), QString("application/octet-stream"));
61− QCOMPARE(index.data(CategoryResults::Roles::RoleTitle).toString(), QString("Test"));
62− QCOMPARE(index.data(CategoryResults::Roles::RoleComment).toString(), QString("Comment"));
63− QCOMPARE(index.data(CategoryResults::Roles::RoleDndUri).toString(), QString("test:dnd-uri"));
64− auto metadata = index.data(CategoryResults::Roles::RoleMetadata).toHash();
65− QCOMPARE(metadata["metadata-field"].toString(), QString("foo"));
66−}
67−
68−void ResultsTest::testIconColumn_data()
69−{
70− QTest::addColumn<QString>("uri");
71− QTest::addColumn<QString>("giconString");
72− QTest::addColumn<QString>("result");
73−
74− QTest::newRow("unspecified") << "test:uri" << "" << "";
75− QTest::newRow("absolute path") << "test:uri" << "/usr/share/icons/example.png" << "/usr/share/icons/example.png";
76− QTest::newRow("file uri") << "test:uri" << "file:///usr/share/icons/example.png" << "file:///usr/share/icons/example.png";
77− QTest::newRow("http uri") << "test:uri" << "http://images.ubuntu.com/example.jpg" << "http://images.ubuntu.com/example.jpg";
78− QTest::newRow("image uri") << "test:uri" << "image://thumbnail/with/arguments?passed_to=ImageProvider" << "image://thumbnail/with/arguments?passed_to=ImageProvider";
79− QTest::newRow("themed icon") << "test:uri" << "accessories-other" << "image://theme/accessories-other";
80− QTest::newRow("fileicon") << "test:uri" << ". GFileIcon http://example.org/resource.gif" << "http://example.org/resource.gif";
81− QTest::newRow("themedicon") << "test:uri" << ". GThemedIcon accessories-other accessories generic" << "image://theme/accessories-other,accessories,generic";
82− QTest::newRow("annotatedicon") << "test:uri" << ". UnityProtocolAnnotatedIcon %7B'base-icon':%20%3C'.%20GThemedIcon%20accessories-other%20accessories%20generic'%3E%7D" << "image://theme/accessories-other,accessories,generic";
83− QTest::newRow("thumbnailer icon") << "file:///usr/share/samples/video/foo.avi" << "" << "image://thumbnailer//usr/share/samples/video/foo.avi";
84−}
85−
86−void ResultsTest::testIconColumn()
87−{
88− QFETCH(QString, uri);
89− QFETCH(QString, giconString);
90− QFETCH(QString, result);
91− auto deeModel = createBackendModel();
92− dee_model_append (deeModel,
93− uri.toLocal8Bit().constData(),
94− giconString.toLocal8Bit().constData(),
95− 0,
96− 0,
97− "application/octet-stream",
98− "Test",
99− "",
100− "test:dnd-uri",
101− g_variant_new_array(g_variant_type_element(G_VARIANT_TYPE_VARDICT), NULL, 0));
102−
103− CategoryResults* results = new CategoryResults(this);
104− results->setModel(deeModel);
105−
106− auto index = results->index(0, 0); // there's just one result
107− auto transformedIcon = index.data(CategoryResults::Roles::RoleIconHint).toString();
108− QCOMPARE(transformedIcon, result);
109−}
110−
111−class GVariantWrapper
112−{
113−public:
114− GVariantWrapper() : variant(NULL) {}
115− GVariantWrapper(GVariant* v) {
116− variant = v ? g_variant_ref_sink(v) : NULL;
117− }
118− GVariantWrapper(const GVariantWrapper& other) {
119− variant = other.variant ? g_variant_ref(other.variant) : NULL;
120− }
121− ~GVariantWrapper() {
122− if (variant) g_variant_unref(variant);
123− }
124−
125− GVariant* variant;
126−};
127−
128−Q_DECLARE_METATYPE(GVariantWrapper)
129−
130−void ResultsTest::testSpecialIcons_data()
131−{
132− QTest::addColumn<QString>("uri");
133− QTest::addColumn<GVariantWrapper>("metadata");
134− QTest::addColumn<QString>("result");
135−
136− GVariant *inner;
137− GVariantBuilder builder, inner_builder;
138−
139− g_variant_builder_init(&inner_builder, G_VARIANT_TYPE_VARDICT);
140− g_variant_builder_add(&inner_builder, "{sv}", "artist", g_variant_new_string("U2"));
141− g_variant_builder_add(&inner_builder, "{sv}", "album", g_variant_new_string("War"));
142−
143− g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
144− g_variant_builder_add(&builder, "{sv}", "content", g_variant_builder_end(&inner_builder));
145−
146− QTest::newRow("simple") << "file:///foo.mp3" << GVariantWrapper(g_variant_builder_end(&builder)) << "image://albumart/U2/War";
147−
148− g_variant_builder_init(&inner_builder, G_VARIANT_TYPE_VARDICT);
149− g_variant_builder_add(&inner_builder, "{sv}", "artist", g_variant_new_string("U2"));
150− g_variant_builder_add(&inner_builder, "{sv}", "album", g_variant_new_string("War/Joshua tree"));
151− inner = g_variant_builder_end(&inner_builder);
152−
153− g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
154− g_variant_builder_add(&builder, "{sv}", "content", inner);
155−
156− QTest::newRow("with-slash") << "file:///foo.mp3" << GVariantWrapper(g_variant_builder_end(&builder)) << "image://albumart/U2/War%2FJoshua%20tree";
157−
158− g_variant_builder_init(&inner_builder, G_VARIANT_TYPE_VARDICT);
159− g_variant_builder_add(&inner_builder, "{sv}", "artist", g_variant_new_string("U2"));
160− g_variant_builder_add(&inner_builder, "{sv}", "album", g_variant_new_string("War"));
161− inner = g_variant_builder_end(&inner_builder);
162−
163− g_variant_builder_init(&inner_builder, G_VARIANT_TYPE_VARDICT);
164− g_variant_builder_add(&inner_builder, "{sv}", "content", inner);
165−
166− g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
167− g_variant_builder_add(&builder, "{sv}", "content", g_variant_builder_end(&inner_builder));
168−
169− QTest::newRow("nested") << "file:///foo.mp3" << GVariantWrapper(g_variant_builder_end(&builder)) << "image://albumart/U2/War";
170−}
171−
172−void ResultsTest::testSpecialIcons()
173−{
174− QFETCH(QString, uri);
175− QFETCH(GVariantWrapper, metadata);
176− QFETCH(QString, result);
177− auto deeModel = createBackendModel();
178− dee_model_append (deeModel,
179− uri.toLocal8Bit().constData(),
180− "",
181− 0,
182− 0,
183− "audio/mp3",
184− "Test",
185− "",
186− uri.toLocal8Bit().constData(),
187− metadata.variant);
188−
189− CategoryResults* results = new CategoryResults(this);
190− results->setModel(deeModel);
191−
192− auto index = results->index(0, 0); // there's just one result
193− auto transformedIcon = index.data(CategoryResults::Roles::RoleIconHint).toString();
194− QCOMPARE(transformedIcon, result);
195−}
196−
197−void ResultsTest::testMetadataOverride_data()
198−{
199− QTest::addColumn<QString>("uri");
200− QTest::addColumn<QVariantHash>("result");
201−
202− QVariantHash expected_result;
203− QVariantHash inner_hash;
204−
205− expected_result = QVariantHash();
206− expected_result["scope-id"] = QVariant::fromValue(QString("applications.scope"));
207− expected_result["content"] = QVariant::fromValue(QVariantHash());
208−
209− QTest::newRow("single scope") << "subscope:applications.scope" << expected_result;
210−
211− expected_result = QVariantHash();
212− expected_result["scope-id"] = QVariant::fromValue(QString("applications.scope"));
213− inner_hash = QVariantHash();
214− inner_hash["foo"] = QVariant::fromValue(QString("bar"));
215− inner_hash["qoo"] = QVariant::fromValue(QString("baz"));
216− expected_result["content"] = QVariant::fromValue(inner_hash);
217−
218− QTest::newRow("single scope with data") << "subscope:applications.scope?foo=bar&qoo=baz" << expected_result;
219−
220− expected_result = QVariantHash();
221− inner_hash = QVariantHash();
222− inner_hash["scope-id"] = QVariant::fromValue(QString("applications-local.scope"));
223− inner_hash["content"] = QVariant::fromValue(QVariantHash());
224− expected_result["scope-id"] = QVariant::fromValue(QString("applications.scope"));
225− expected_result["content"] = QVariant::fromValue(inner_hash);
226− QTest::newRow("master scope") << "subscope:applications.scope/applications-local.scope" << expected_result;
227−
228− expected_result = QVariantHash();
229− expected_result["foo"] = QVariant::fromValue(QString("baz"));
230− expected_result["qoo"] = QVariant::fromValue(QString("baz"));
231− inner_hash = QVariantHash();
232− inner_hash["scope-id"] = QVariant::fromValue(QString("applications-local.scope"));
233− inner_hash["content"] = QVariant::fromValue(expected_result);
234− expected_result = QVariantHash();
235− expected_result["scope-id"] = QVariant::fromValue(QString("applications.scope"));
236− expected_result["content"] = QVariant::fromValue(inner_hash);
237− QTest::newRow("nested with data") << "subscope:applications.scope/applications-local.scope?foo=baz&qoo=baz" << expected_result;
238−}
239−
240−void ResultsTest::testMetadataOverride()
241−{
242− QFETCH(QString, uri);
243− QFETCH(QVariantHash, result);
244−
245− QCOMPARE(subscopeUriToMetadataHash(uri), result);
246−}
247−
248−QTEST_MAIN(ResultsTest)
tests/plugins/Unity/signalslisttest.cppdeleted−57
@@ -1,57 +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−// local
18−#include "signalslisttest.h"
19−#include "signalslist.h"
20−
21−// Qt
22−#include <QTest>
23−
24−class TestSource
25−{
26− public:
27− TestSource(): m_count(0) {}
28− void update()
29− {
30− countChanged(++m_count);
31− }
32−
33− sigc::signal<void, int> countChanged;
34− int m_count;
35−};
36−
37−void SignalsListTest::testSignalsList()
38−{
39− TestSource src;
40− SignalsList signals;
41− int counter = -1;
42−
43− signals << src.countChanged.connect([&counter](int val) {
44− counter = val;
45− });
46−
47− src.update();
48− QCOMPARE(counter, 1);
49− src.update();
50− QCOMPARE(counter, 2);
51−
52− signals.disconnectAll();
53− src.update();
54− QCOMPARE(counter, 2);
55−}
56−
57−QTEST_MAIN(SignalsListTest)
tests/qmltests/CMakeLists.txt+5−5
@@ -13,11 +13,8 @@ set(qmltest_DEFAULT_NO_ADD_TEST FALSE)
13set(qmltest_DEFAULT_PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=minimal")
13set(qmltest_DEFAULT_PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=minimal")
14add_qml_test(Components AnimationControllerWithSignals)
14add_qml_test(Components AnimationControllerWithSignals)
15add_qml_test(Components Carousel)
15add_qml_test(Components Carousel)
16−add_qml_test(Components MathLocal)
17add_qml_test(Components OpenEffect)
16add_qml_test(Components OpenEffect)
18add_qml_test(Components RatingStars)
17add_qml_test(Components RatingStars)
19−add_qml_test(Components TimeLocal)
20−add_qml_test(Greeter Clock IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins)
21add_qml_test(Panel IndicatorItem)
18add_qml_test(Panel IndicatorItem)
22add_qml_test(utils/Unity/Test UnityTest)
19add_qml_test(utils/Unity/Test UnityTest)
23
20
@@ -47,7 +44,6 @@ add_qml_test(Dash DashContent IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest
47add_qml_test(Dash DashPreview)
44add_qml_test(Dash DashPreview)
48add_qml_test(Dash GenericPreview)
45add_qml_test(Dash GenericPreview)
49add_qml_test(Dash GenericScopeView IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
46add_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})
51add_qml_test(Dash FilterGrids IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins ${CMAKE_CURRENT_SOURCE_DIR}/plugins
47add_qml_test(Dash FilterGrids IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins ${CMAKE_CURRENT_SOURCE_DIR}/plugins
52 ${CMAKE_BINARY_DIR}/tests/mocks)
48 ${CMAKE_BINARY_DIR}/tests/mocks)
53add_qml_test(Dash/Apps RunningApplicationsGrid IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
49add_qml_test(Dash/Apps RunningApplicationsGrid IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
@@ -61,15 +57,19 @@ add_qml_test(Greeter Phone IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DE
61 ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
57 ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
62add_qml_test(Greeter Infographics IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
58add_qml_test(Greeter Infographics IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
63 ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full")
59 ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full")
60+add_qml_test(Greeter Clock IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
61+ ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
64add_qml_test(Hud Hud)
62add_qml_test(Hud Hud)
65add_qml_test(Hud Result)
63add_qml_test(Hud Result)
66add_qml_test(Launcher Launcher IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
64add_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)
65+add_qml_test(Notifications Notifications IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins)
68add_qml_test(Panel IndicatorRow)
66add_qml_test(Panel IndicatorRow)
69add_qml_test(Panel Indicators IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
67add_qml_test(Panel Indicators IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
70add_qml_test(Panel MenuContent IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
68add_qml_test(Panel MenuContent IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
71add_qml_test(Panel Panel IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
69add_qml_test(Panel Panel IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
72add_qml_test(Panel SearchIndicator)
70add_qml_test(Panel SearchIndicator)
71+add_qml_test(Panel/Indicators DefaultIndicatorWidget IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
72+ ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
73add_qml_test(SideStage SideStage IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS}
73add_qml_test(SideStage SideStage IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS}
74 ${CMAKE_BINARY_DIR}/tests/mocks
74 ${CMAKE_BINARY_DIR}/tests/mocks
75 ${CMAKE_BINARY_DIR}/plugins)
75 ${CMAKE_BINARY_DIR}/plugins)
tests/qmltests/Components/tst_DragHandle.cpp+4−5
@@ -41,7 +41,7 @@ class FakeTimeSource : public UbuntuGestures::TimeSource
41{
41{
42public:
42public:
43 FakeTimeSource() { m_msecsSinceReference = 0; }
43 FakeTimeSource() { m_msecsSinceReference = 0; }
44− virtual qint64 msecsSinceReference() {return m_msecsSinceReference;}
44+ qint64 msecsSinceReference() override {return m_msecsSinceReference;}
45 qint64 m_msecsSinceReference;
45 qint64 m_msecsSinceReference;
46};
46};
47
47
@@ -73,7 +73,7 @@ private:
73 QQuickView *m_view;
73 QQuickView *m_view;
74 QTouchDevice *m_device;
74 QTouchDevice *m_device;
75 FakeTimer *m_fakeTimer;
75 FakeTimer *m_fakeTimer;
76− FakeTimeSource *m_fakeTimeSource;
76+ QSharedPointer<FakeTimeSource> m_fakeTimeSource;
77};
77};
78
78
79
79
@@ -102,7 +102,7 @@ void tst_DragHandle::init()
102 qApp->processEvents();
102 qApp->processEvents();
103
103
104 m_fakeTimer = new FakeTimer;
104 m_fakeTimer = new FakeTimer;
105− m_fakeTimeSource = new FakeTimeSource;
105+ m_fakeTimeSource.reset(new FakeTimeSource);
106}
106}
107
107
108void tst_DragHandle::cleanup()
108void tst_DragHandle::cleanup()
@@ -113,8 +113,7 @@ void tst_DragHandle::cleanup()
113 delete m_fakeTimer;
113 delete m_fakeTimer;
114 m_fakeTimer = 0;
114 m_fakeTimer = 0;
115
115
116− delete m_fakeTimeSource;
116+ m_fakeTimeSource.reset();
117− m_fakeTimeSource = 0;
118}
117}
119
118
120QQuickView *tst_DragHandle::createView()
119QQuickView *tst_DragHandle::createView()
tests/qmltests/Components/tst_EdgeDemoOverlay.qml+2−2
@@ -112,8 +112,8 @@ Item {
112 // Test that the 'none' edge skips anywhere
112 // Test that the 'none' edge skips anywhere
113 signalSpy.target = none
113 signalSpy.target = none
114 signalSpy.clear()
114 signalSpy.clear()
115− var backgroundShade = findChild(none, "backgroundShade")
115+ var backgroundShade = findChild(none, "backgroundShadeMouseArea")
116− tryCompare(none, "opacity", 1)
116+ tryCompare(backgroundShade, "enabled", true)
117 mousePress(backgroundShade, 1, 1)
117 mousePress(backgroundShade, 1, 1)
118 mouseRelease(backgroundShade, 1, 1)
118 mouseRelease(backgroundShade, 1, 1)
119 signalSpy.wait()
119 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+44−3
@@ -37,6 +37,10 @@ Item {
37 property alias searchEnabled : pageHeader.searchEntryEnabled
37 property alias searchEnabled : pageHeader.searchEntryEnabled
38 property alias searchQuery : pageHeader.searchQuery
38 property alias searchQuery : pageHeader.searchQuery
39
39
40+ function init() {
41+ searchEnabled = true;
42+ }
43+
40 function test_search_disabled() {
44 function test_search_disabled() {
41 searchEnabled = false
45 searchEnabled = false
42 pageHeader.resetSearch()
46 pageHeader.resetSearch()
@@ -151,12 +155,48 @@ Item {
151 scopeMock.searchInProgress = true
155 scopeMock.searchInProgress = true
152 compare(searchIndicator.running, true, "Search indicator isn't running.")
156 compare(searchIndicator.running, true, "Search indicator isn't running.")
153 tryCompare(primaryImage, "visible", false)
157 tryCompare(primaryImage, "visible", false)
154−
155− pageHeader.resetSearch()
156 }
158 }
157
159
158 function cleanup() {
160 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);
160 }
200 }
161 }
201 }
162
202
@@ -174,6 +214,7 @@ Item {
174 scope: scopeMock
214 scope: scopeMock
175
215
176 searchEntryEnabled: true
216 searchEntryEnabled: true
217+ searchHistory: SearchHistoryModel {}
177 text: "%^$%^%^&%^&%^$%GHR%"
218 text: "%^$%^%^&%^&%^$%GHR%"
178 }
219 }
179
220
tests/qmltests/Components/tst_TimeLocal.qmldeleted−117
@@ -1,117 +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/Time.js" as TimeLocal
20−
21−TestCase {
22− name: "TimeLocal"
23−
24− property var readableDate
25−
26− function test_readableFromNow_dateUndefined() {
27− readableDate = TimeLocal.readableFromNow()
28− compare(readableDate, "", "readable date should have been null")
29− }
30−
31− function test_readableFromNow_dateNaN() {
32− readableDate = TimeLocal.readableFromNow("this is a string, not a date")
33− compare(readableDate, "", "readable date should have been null")
34− }
35−
36− function test_readableFromNow_justNow() {
37− readableDate = TimeLocal.readableFromNow(new Date())
38− compare(readableDate, "just now", "readable date should have been now")
39− }
40−
41− function test_readableFromNow_nowNaN() {
42− var fail = false
43− try {
44− TimeLocal.readableFromNow(new Date(), "this is a string, not a date")
45− } catch (err) {
46− fail = true
47− } finally {
48− compare(fail, true, "readable date should have thrown an exception")
49− }
50− }
51−
52− function cycleTime(diff, previous, next, units, endIterator) {
53− var now = new Date()
54− var time = now.getTime()
55− readableDate = TimeLocal.readableFromNow(time - diff, now)
56− compare(readableDate, previous, "different time predicted")
57− readableDate = TimeLocal.readableFromNow(time + diff, now)
58− compare(readableDate, next, "different time predicted")
59− for (var i = 2; i < endIterator; i++) {
60− var tmpDiff = i * diff
61− readableDate = TimeLocal.readableFromNow(time - tmpDiff, now)
62− compare(readableDate, i + " " + units + " ago", "different time predicted")
63− readableDate = TimeLocal.readableFromNow(time + tmpDiff, now)
64− compare(readableDate, "in " + i + " " + units, "different time predicted")
65− }
66− }
67−
68− function test_readableFromNow_seconds() {
69− cycleTime(1000, "a second ago", "in a second", "seconds", 60)
70− }
71−
72− function test_readableFromNow_minutes() {
73− cycleTime(1000 * 60, "a minute ago", "in a minute", "minutes", 60)
74− }
75−
76− function test_readableFromNow_hours() {
77− cycleTime(1000 * 60 * 60, "an hour ago", "in an hour", "hours", 24)
78− }
79−
80− function test_readableFromNow_days() {
81− cycleTime(1000 * 60 * 60 * 24, "yesterday", "tomorrow", "days", 7)
82− }
83−
84− function test_readableFromNow_weeks() {
85− var now = new Date()
86− for (var i = 7; i < 30; i++) {
87− readableDate = TimeLocal.readableFromNow(now.getTime() - i * 1000 * 60 * 60 * 24, now)
88− if (i < 14)
89− compare(readableDate, "a week ago", "different time predicted")
90− else if (i < 18)
91− compare(readableDate, "about 2 weeks ago", "different time predicted")
92− else if (i < 25)
93− compare(readableDate, "about 3 weeks ago", "different time predicted")
94− else
95− compare(readableDate, "about 4 weeks ago", "different time predicted")
96− }
97− for (var i = 7; i < 30; i++) {
98− readableDate = TimeLocal.readableFromNow(now.getTime() + i * 1000 * 60 * 60 * 24, now)
99− if (i < 14)
100− compare(readableDate, "in a week", "different time predicted")
101− else if (i < 18)
102− compare(readableDate, "in about 2 weeks", "different time predicted")
103− else if (i < 25)
104− compare(readableDate, "in about 3 weeks", "different time predicted")
105− else
106− compare(readableDate, "in about 4 weeks", "different time predicted")
107− }
108− }
109−
110− function test_readableFromNow_months() {
111− cycleTime(1000 * 60 * 60 * 24 * 30.45, "a month ago", "in a month", "months", 12)
112− }
113−
114− function test_readableFromNow_years() {
115− cycleTime(1000 * 60 * 60 * 24 * 366, "a year ago", "in a year", "years", 5)
116− }
117−}
tests/qmltests/Dash/Apps/tst_RunningApplicationsGrid.qml+1
@@ -226,6 +226,7 @@ Item {
226 verify(fakeRunningAppsModel.contains("calendar"))
226 verify(fakeRunningAppsModel.contains("calendar"))
227
227
228 mouseClick(calendarTileCloseButton, calendarTileCloseButton.width/2, calendarTileCloseButton.height/2)
228 mouseClick(calendarTileCloseButton, calendarTileCloseButton.width/2, calendarTileCloseButton.height/2)
229+ wait(0) // spin event loop to start any pending animation
229
230
230 verify(!fakeRunningAppsModel.contains("calendar"))
231 verify(!fakeRunningAppsModel.contains("calendar"))
231
232
tests/qmltests/Dash/qml/FakeScopeView.qml+3−68
@@ -19,13 +19,13 @@ import Unity 0.1
19
19
20import "../../../../Dash"
20import "../../../../Dash"
21
21
22−ScopeView {
22+GenericScopeView {
23 id: fakeScopeView
23 id: fakeScopeView
24
24
25 property alias backColor : back.color
25 property alias backColor : back.color
26
26
27 onEndReached: {
27 onEndReached: {
28− if (shell != undefined && shell.scopeStatus != undefined) {
28+ if (scope != undefined && shell != undefined && shell.scopeStatus != undefined) {
29 shell.scopeStatus[scope.id].endReached++;
29 shell.scopeStatus[scope.id].endReached++;
30 }
30 }
31 }
31 }
@@ -44,71 +44,6 @@ ScopeView {
44 id: back
44 id: back
45 anchors.fill: parent
45 anchors.fill: parent
46 color: "grey"
46 color: "grey"
47− }
47+ z: -1
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− }
113 }
48 }
114}
49}
tests/qmltests/Dash/tst_Dash.qml+7−1
@@ -102,9 +102,15 @@ Item {
102 console.log("Not testing " + data.tag + ": not visible");
102 console.log("Not testing " + data.tag + ": not visible");
103 return;
103 return;
104 }
104 }
105+ var dashContentList = findChild(dash, "dashContentList");
106+
105 dash.showScopeOnLoaded = data.tag
107 dash.showScopeOnLoaded = data.tag
108+ scopes.clear();
109+ tryCompare(dashContentList, "count", 0);
110+ scopes.load();
111+ tryCompare(scopes, "loaded", true);
112+ tryCompare(dashContentList, "count", 4);
106
113
107− var dashContentList = findChild(dash, "dashContentList");
108 verify(dashContentList != undefined);
114 verify(dashContentList != undefined);
109 tryCompare(dashContentList, "currentIndex", data.visualIndex);
115 tryCompare(dashContentList, "currentIndex", data.visualIndex);
110 }
116 }
tests/qmltests/Dash/tst_DashContent.qml+37−3
@@ -26,7 +26,17 @@ Item {
26 width: units.gu(40)
26 width: units.gu(40)
27 height: units.gu(80)
27 height: units.gu(80)
28
28
29− property ListModel searchHistory: ListModel {}
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+ }
30
40
31 property var scopeStatus: {
41 property var scopeStatus: {
32 'MockScope1': { 'movementStarted': 0, 'positionedAtBeginning': 0 },
42 'MockScope1': { 'movementStarted': 0, 'positionedAtBeginning': 0 },
@@ -48,6 +58,7 @@ Item {
48 scopes : scopesModel
58 scopes : scopesModel
49
59
50 scopeMapper : scopeDelegateMapper
60 scopeMapper : scopeDelegateMapper
61+ searchHistory: ListModel {}
51 }
62 }
52
63
53 ScopeDelegateMapper {
64 ScopeDelegateMapper {
@@ -111,10 +122,10 @@ Item {
111 clear_scope_status();
122 clear_scope_status();
112 dashContent.visible = true;
123 dashContent.visible = true;
113
124
114− scopesModel.clear();
115− // wait for dash to empty scopes.
116 var dashContentList = findChild(dashContent, "dashContentList");
125 var dashContentList = findChild(dashContent, "dashContentList");
117 verify(dashContentList != undefined);
126 verify(dashContentList != undefined);
127+ scopesModel.clear();
128+ // wait for dash to empty scopes.
118 tryCompare(dashContentList, "count", 0);
129 tryCompare(dashContentList, "count", 0);
119 }
130 }
120
131
@@ -229,5 +240,28 @@ Item {
229 tryCompare(scopesModel.get(1), "isActive", data.active1);
240 tryCompare(scopesModel.get(1), "isActive", data.active1);
230 tryCompare(scopesModel.get(2), "isActive", data.active2);
241 tryCompare(scopesModel.get(2), "isActive", data.active2);
231 }
242 }
243+
244+ function checkFlickMovingAndNotInteractive()
245+ {
246+ var dashContentList = findChild(dashContent, "dashContentList");
247+
248+ if (dashContentList.currentItem.moving && !dashContentList.interactive)
249+ return true;
250+
251+ var startX = dashContentList.width/2;
252+ var startY = dashContentList.height/2;
253+ touchFlick(dashContentList, startX, startY, startX, startY - units.gu(40));
254+
255+ return dashContentList.currentItem.moving && !dashContentList.interactive;
256+ }
257+
258+
259+ function test_hswipe_disabled_vswipe() {
260+ var dashContentList = findChild(dashContent, "dashContentList");
261+
262+ tryCompare(dashContentList, "interactive", true);
263+
264+ tryCompareFunction(checkFlickMovingAndNotInteractive, true);
265+ }
232 }
266 }
233}
267}
tests/qmltests/Dash/tst_FilterGrids.qml+1−2
@@ -108,8 +108,7 @@ Rectangle {
108 function test_clicked_signal_data() {
108 function test_clicked_signal_data() {
109 return [
109 return [
110 {tag: "VideoFilterGrid", component: "Video/VideoFilterGrid.qml"},
110 {tag: "VideoFilterGrid", component: "Video/VideoFilterGrid.qml"},
111− {tag: "MusicFilterGrid", component: "Music/MusicFilterGrid.qml"},
111+ {tag: "MusicFilterGrid", component: "Music/MusicFilterGrid.qml"}
112− {tag: "ApplicationsFilterGrid", component: "Apps/ApplicationsFilterGrid.qml"}
113 ]
112 ]
114 }
113 }
115
114
tests/qmltests/Dash/tst_GenericScopeView.qml+27−2
@@ -74,6 +74,9 @@ Item {
74 }
74 }
75
75
76 function openPreview() {
76 function openPreview() {
77+ var categoryListView = findChild(genericScopeView, "categoryListView");
78+ categoryListView.positionAtBeginning();
79+
77 var tile = findChild(genericScopeView, "delegate0");
80 var tile = findChild(genericScopeView, "delegate0");
78 mouseClick(tile, tile.width / 2, tile.height / 2);
81 mouseClick(tile, tile.width / 2, tile.height / 2);
79 var openEffect = findChild(genericScopeView, "openEffect");
82 var openEffect = findChild(genericScopeView, "openEffect");
@@ -129,7 +132,23 @@ Item {
129 tryCompare(previewListView, "open", false);
132 tryCompare(previewListView, "open", false);
130 }
133 }
131
134
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() {
133 var previewListView = findChild(genericScopeView, "previewListView");
152 var previewListView = findChild(genericScopeView, "previewListView");
134 tryCompare(previewListView, "open", false);
153 tryCompare(previewListView, "open", false);
135
154
@@ -170,7 +189,6 @@ Item {
170
189
171 checkArrowPosition(i);
190 checkArrowPosition(i);
172 }
191 }
173−
174 closePreview();
192 closePreview();
175 }
193 }
176
194
@@ -187,6 +205,13 @@ Item {
187
205
188 closePreview();
206 closePreview();
189 }
207 }
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+ }
190 }
215 }
191 }
216 }
192}
217}
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
19import ".."
19import ".."
20import "../../../Greeter"
20import "../../../Greeter"
21import Ubuntu.Components 0.1
21import Ubuntu.Components 0.1
22+import QMenuModel 0.1
22import Unity.Test 0.1 as UT
23import Unity.Test 0.1 as UT
23
24
24Rectangle {
25Rectangle {
@@ -35,9 +36,24 @@ Rectangle {
35 }
36 }
36 }
37 }
37
38
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+
38 UT.UnityTestCase {
48 UT.UnityTestCase {
39 name: "Clock"
49 name: "Clock"
40
50
51+ function init() {
52+ var cachedModel = findChild(clock, "timeModel");
53+ verify(cachedModel !== undefined);
54+ cachedModel.model = menuModel;
55+ }
56+
41 function test_customDate() {
57 function test_customDate() {
42 var dateObj = new Date("October 13, 1975 11:13:00")
58 var dateObj = new Date("October 13, 1975 11:13:00")
43 var dateString = Qt.formatDate(dateObj, Qt.DefaultLocaleLongDate)
59 var dateString = Qt.formatDate(dateObj, Qt.DefaultLocaleLongDate)
tests/qmltests/Greeter/tst_Lockscreen.qml+81−15
@@ -41,7 +41,7 @@ Rectangle {
41 target: lockscreen
41 target: lockscreen
42
42
43 onEmergencyCall: emergencyCheckBox.checked = true
43 onEmergencyCall: emergencyCheckBox.checked = true
44− onUnlocked: unlockedCheckBox.checked = true
44+ onEntered: enteredLabel.text = passphrase
45 }
45 }
46
46
47 Connections {
47 Connections {
@@ -99,12 +99,11 @@ Rectangle {
99 anchors.verticalCenter: parent.verticalCenter
99 anchors.verticalCenter: parent.verticalCenter
100 }
100 }
101 Row {
101 Row {
102− CheckBox {
102+ Label {
103− id: unlockedCheckBox
103+ text: "Entered:"
104 }
104 }
105 Label {
105 Label {
106− text: "Unlocked signal"
106+ id: enteredLabel
107− anchors.verticalCenter: parent.verticalCenter
108 }
107 }
109 }
108 }
110 Button {
109 Button {
@@ -176,15 +175,17 @@ Rectangle {
176
175
177 function test_unlock_data() {
176 function test_unlock_data() {
178 return [
177 return [
179− {tag: "numeric", alphanumeric: false, username: "has-pin", password: "1234", unlockedSignal: true},
178+ {tag: "numeric", alphanumeric: false, username: "has-pin", password: "1234", pinLength: 4},
180− {tag: "alphanumeric", alphanumeric: true, username: "has-password", password: "password", unlockedSignal: true},
179+ {tag: "alphanumeric", alphanumeric: true, username: "has-password", password: "password", pinLength: -1},
181− {tag: "numeric (wrong)", alphanumeric: false, username: "has-pin", password: "4321", unlockedSignal: false},
180+ {tag: "numeric (wrong)", alphanumeric: false, username: "has-pin", password: "4321", pinLength: 4},
182− {tag: "alphanumeric (wrong)", alphanumeric: true, username: "has-password", password: "drowssap", unlockedSignal: false},
181+ {tag: "alphanumeric (wrong)", alphanumeric: true, username: "has-password", password: "drowssap", pinLength: -1},
182+ {tag: "flexible length", alphanumeric: false, username: "has-pin", password: "1234", pinLength: -1},
183 ]
183 ]
184 }
184 }
185
185
186 function test_unlock(data) {
186 function test_unlock(data) {
187− unlockedCheckBox.checked = false
187+ enteredLabel.text = ""
188+ pinLengthTextField.text = data.pinLength
188 LightDM.Greeter.authenticate(data.username)
189 LightDM.Greeter.authenticate(data.username)
189 waitForRendering(lockscreen)
190 waitForRendering(lockscreen)
190
191
@@ -199,14 +200,79 @@ Rectangle {
199 var button = findChild(lockscreen, "pinPadButton" + character)
200 var button = findChild(lockscreen, "pinPadButton" + character)
200 mouseClick(button, units.gu(1), units.gu(1))
201 mouseClick(button, units.gu(1), units.gu(1))
201 }
202 }
203+ if (data.pinLength == -1) {
204+ var pinPadButtonErase = findChild(lockscreen, "pinPadButtonErase");
205+ mouseClick(pinPadButtonErase, units.gu(1), units.gu(1));
206+ }
207+ }
208+ tryCompare(enteredLabel, "text", data.password)
209+ }
210+
211+ function test_clear_data() {
212+ return [
213+ {tag: "animated PIN", animation: true, alphanumeric: false},
214+ {tag: "not animated PIN", animation: false, alphanumeric: false},
215+ {tag: "animated passphrase", animation: true, alphanumeric: true},
216+ {tag: "not animated passphrase", animation: false, alphanumeric: true}
217+ ];
218+ }
219+
220+ function test_clear(data) {
221+ pinPadCheckBox.checked = data.alphanumeric
222+ waitForRendering(lockscreen)
223+
224+ var inputField = findChild(lockscreen, "pinentryField")
225+ if (data.alphanumeric) {
226+ mouseClick(inputField, units.gu(1), units.gu(1))
227+ typeString("1")
228+ } else {
229+ var button = findChild(lockscreen, "pinPadButton1")
230+ mouseClick(button, units.gu(1), units.gu(1))
202 }
231 }
203− tryCompare(unlockedCheckBox, "checked", data.unlockedSignal)
232+
204− if (!data.unlockedSignal) {
233+ var animation = findInvisibleChild(lockscreen, "wrongPasswordAnimation")
205− // make sure the input is cleared on wrong input
234+
206− tryCompareFunction(function() {return inputField.text.length == 0}, true)
235+ tryCompare(inputField, "text", "1")
236+
237+ lockscreen.clear(data.animation)
238+ tryCompare(inputField, "text", "")
239+
240+ wait(0) // Trigger event loop to make sure the animation would start running
241+ compare(animation.running, data.animation)
242+
243+ // wait for animation to finish to not disturb other tests
244+ tryCompare(animation, "running", false)
245+ }
246+
247+ function test_backspace_data() {
248+ return [
249+ {tag: "fixed length", pinLength: 4},
250+ {tag: "variable length", pinLength: -1}
251+ ];
252+ }
253+
254+ function test_backspace(data) {
255+ pinPadCheckBox.checked = false
256+ pinLengthTextField.text = data.pinLength
257+ waitForRendering(lockscreen);
258+
259+ var pinPadButtonErase = findChild(lockscreen, "pinPadButtonErase");
260+ var backspaceIcon = findChild(lockscreen, "backspaceIcon");
261+ var pinEntryField = findChild(lockscreen, "pinentryField");
262+
263+ compare(pinPadButtonErase.iconName, data.pinLength == -1 ? "" : "erase");
264+ compare(backspaceIcon.visible, data.pinLength == -1);
265+
266+ var pinPadButton5 = findChild(lockscreen, "pinPadButton5");
267+ mouseClick(pinPadButton5, units.gu(1), units.gu(1));
268+ compare(pinEntryField.text, "5");
269+
270+ if (data.pinLength == -1) {
271+ mouseClick(backspaceIcon, units.gu(1), units.gu(1));
207 } else {
272 } else {
208− tryCompareFunction(function() {return inputField.text.length > 0}, true)
273+ mouseClick(pinPadButtonErase, units.gu(1), units.gu(1));
209 }
274 }
275+ compare(pinEntryField.text, "");
210 }
276 }
211 }
277 }
212}
278}
tests/qmltests/Greeter/tst_Phone.qml+5−5
@@ -133,7 +133,7 @@ Item {
133 tryCompare(LightDM.Infographic, "username", "single")
133 tryCompare(LightDM.Infographic, "username", "single")
134 }
134 }
135
135
136− function test_wallpaper_data() {
136+ function test_background_data() {
137 return [
137 return [
138 {tag: "set", accounts: "../tests/data/unity/backgrounds/blue.png", expected: "blue.png"},
138 {tag: "set", accounts: "../tests/data/unity/backgrounds/blue.png", expected: "blue.png"},
139 {tag: "unset", accounts: "", expected: "background.jpg"},
139 {tag: "unset", accounts: "", expected: "background.jpg"},
@@ -141,12 +141,12 @@ Item {
141 ]
141 ]
142 }
142 }
143
143
144− function test_wallpaper(data) {
144+ function test_background(data) {
145 var loader = findChild(greeter, "greeterContentLoader")
145 var loader = findChild(greeter, "greeterContentLoader")
146− var wallpaper = findChild(loader.item, "wallpaper")
146+ var background = findChild(loader.item, "greeterBackground")
147 AccountsService.backgroundFile = data.accounts
147 AccountsService.backgroundFile = data.accounts
148− tryCompareFunction(function() { return wallpaper.source.toString().indexOf(data.expected) !== -1; }, true)
148+ tryCompareFunction(function() { return background.source.toString().indexOf(data.expected) !== -1; }, true)
149− tryCompare(wallpaper, "status", Image.Ready)
149+ tryCompare(background, "status", Image.Ready)
150 }
150 }
151 }
151 }
152}
152}
tests/qmltests/Notifications/tst_Notifications.qml+56
@@ -76,6 +76,20 @@ Row {
76 mockModel.append(n)
76 mockModel.append(n)
77 }
77 }
78
78
79+ function addEphemeralNonShapedIconNotification() {
80+ var n = {
81+ type: Notification.Ephemeral,
82+ hints: {"x-canonical-non-shaped-icon": "true"},
83+ summary: "Contacts",
84+ body: "Synchronised contacts-database with cloud-storage.",
85+ icon: "../graphics/applicationIcons/contacts-app.png",
86+ secondaryIcon: "",
87+ actions: []
88+ }
89+
90+ mockModel.append(n)
91+ }
92+
79 function addEphemeralIconSummaryNotification() {
93 function addEphemeralIconSummaryNotification() {
80 var n = {
94 var n = {
81 type: Notification.Ephemeral,
95 type: Notification.Ephemeral,
@@ -156,6 +170,12 @@ Row {
156 onClicked: addEphemeralNotification()
170 onClicked: addEphemeralNotification()
157 }
171 }
158
172
173+ Button {
174+ width: parent.width
175+ text: "add an non-shaped-icon-summary-body"
176+ onClicked: addEphemeralNonShapedIconNotification()
177+ }
178+
159 Button {
179 Button {
160 width: parent.width
180 width: parent.width
161 text: "add an icon-summary"
181 text: "add an icon-summary"
@@ -206,6 +226,8 @@ Row {
206 bodyVisible: true,
226 bodyVisible: true,
207 interactiveAreaEnabled: false,
227 interactiveAreaEnabled: false,
208 iconVisible: true,
228 iconVisible: true,
229+ shapedIcon: true,
230+ nonShapedIcon: false,
209 secondaryIconVisible: true,
231 secondaryIconVisible: true,
210 buttonRowVisible: true,
232 buttonRowVisible: true,
211 buttonTinted: true
233 buttonTinted: true
@@ -223,6 +245,8 @@ Row {
223 bodyVisible: false,
245 bodyVisible: false,
224 interactiveAreaEnabled: false,
246 interactiveAreaEnabled: false,
225 iconVisible: false,
247 iconVisible: false,
248+ shapedIcon: false,
249+ nonShapedIcon: false,
226 secondaryIconVisible: true,
250 secondaryIconVisible: true,
227 buttonRowVisible: false,
251 buttonRowVisible: false,
228 buttonTinted: false
252 buttonTinted: false
@@ -240,6 +264,8 @@ Row {
240 bodyVisible: false,
264 bodyVisible: false,
241 interactiveAreaEnabled: false,
265 interactiveAreaEnabled: false,
242 iconVisible: false,
266 iconVisible: false,
267+ shapedIcon: false,
268+ nonShapedIcon: false,
243 secondaryIconVisible: true,
269 secondaryIconVisible: true,
244 buttonRowVisible: false,
270 buttonRowVisible: false,
245 buttonTinted: false
271 buttonTinted: false
@@ -257,6 +283,8 @@ Row {
257 bodyVisible: true,
283 bodyVisible: true,
258 interactiveAreaEnabled: true,
284 interactiveAreaEnabled: true,
259 iconVisible: true,
285 iconVisible: true,
286+ shapedIcon: true,
287+ nonShapedIcon: false,
260 secondaryIconVisible: false,
288 secondaryIconVisible: false,
261 buttonRowVisible: false,
289 buttonRowVisible: false,
262 buttonTinted: false
290 buttonTinted: false
@@ -275,6 +303,8 @@ Row {
275 bodyVisible: true,
303 bodyVisible: true,
276 interactiveAreaEnabled: false,
304 interactiveAreaEnabled: false,
277 iconVisible: true,
305 iconVisible: true,
306+ shapedIcon: true,
307+ nonShapedIcon: false,
278 secondaryIconVisible: false,
308 secondaryIconVisible: false,
279 buttonRowVisible: true,
309 buttonRowVisible: true,
280 buttonTinted: false
310 buttonTinted: false
@@ -292,9 +322,31 @@ Row {
292 bodyVisible: true,
322 bodyVisible: true,
293 interactiveAreaEnabled: false,
323 interactiveAreaEnabled: false,
294 iconVisible: true,
324 iconVisible: true,
325+ shapedIcon: true,
326+ nonShapedIcon: false,
295 secondaryIconVisible: true,
327 secondaryIconVisible: true,
296 buttonRowVisible: false,
328 buttonRowVisible: false,
297 buttonTinted: false
329 buttonTinted: false
330+ },
331+ {
332+ tag: "Ephemeral notification with non-shaped icon",
333+ type: Notification.Ephemeral,
334+ hints: {"x-canonical-private-button-tint": "false",
335+ "x-canonical-non-shaped-icon": "true"},
336+ summary: "Contacts",
337+ body: "Synchronised contacts-database with cloud-storage.",
338+ icon: "../graphics/applicationIcons/contacts-app.png",
339+ secondaryIcon: "",
340+ actions: [],
341+ summaryVisible: true,
342+ bodyVisible: true,
343+ interactiveAreaEnabled: false,
344+ iconVisible: true,
345+ shapedIcon: false,
346+ nonShapedIcon: true,
347+ secondaryIconVisible: false,
348+ buttonRowVisible: false,
349+ buttonTinted: false
298 }
350 }
299 ]
351 ]
300 }
352 }
@@ -330,6 +382,8 @@ Row {
330 verify(notification !== undefined, "notification wasn't found");
382 verify(notification !== undefined, "notification wasn't found");
331
383
332 var icon = findChild(notification, "icon")
384 var icon = findChild(notification, "icon")
385+ var shapedIcon = findChild(notification, "shapedIcon")
386+ var nonShapedIcon = findChild(notification, "nonShapedIcon")
333 var interactiveArea = findChild(notification, "interactiveArea")
387 var interactiveArea = findChild(notification, "interactiveArea")
334 var secondaryIcon = findChild(notification, "secondaryIcon")
388 var secondaryIcon = findChild(notification, "secondaryIcon")
335 var summaryLabel = findChild(notification, "summaryLabel")
389 var summaryLabel = findChild(notification, "summaryLabel")
@@ -338,6 +392,8 @@ Row {
338 waitForRendering(buttonRow)
392 waitForRendering(buttonRow)
339
393
340 compare(icon.visible, data.iconVisible, "avatar-icon visibility is incorrect")
394 compare(icon.visible, data.iconVisible, "avatar-icon visibility is incorrect")
395+ compare(shapedIcon.visible, data.shapedIcon, "shaped-icon visibility is incorrect")
396+ compare(nonShapedIcon.visible, data.nonShapedIcon, "non-shaped-icon visibility is incorrect")
341 compare(interactiveArea.enabled, data.interactiveAreaEnabled, "check for interactive area")
397 compare(interactiveArea.enabled, data.interactiveAreaEnabled, "check for interactive area")
342
398
343 if(data.interactiveAreaEnabled) {
399 if(data.interactiveAreaEnabled) {
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 {
48
48
49 function get_window_data() {
49 function get_window_data() {
50 return [
50 return [
51+ {tag: "pinned", fullscreenFlag: false, alreadyOpen: false },
52+ {tag: "fullscreen", fullscreenFlag: true, alreadyOpen: false },
51− {tag: "pinned", fullscreenFlag: false },
53+ {tag: "pinned-alreadyOpen", fullscreenFlag: false, alreadyOpen: true },
52− {tag: "fullscreen", fullscreenFlag: true }
54+ {tag: "fullscreen-alreadyOpen", fullscreenFlag: true, alreadyOpen: true }
55+ ];
53− ]}
56+ }
54−
55
57
56 function init() {
58 function init() {
57 searchClicked = false;
59 searchClicked = false;
@@ -135,6 +137,10 @@ Item {
135 // expose more of the panel, binding it to the selected indicator and opening it's menu.
137 // expose more of the panel, binding it to the selected indicator and opening it's menu.
136 function test_drag_show(data) {
138 function test_drag_show(data) {
137 panel.fullscreenMode = data.fullscreenFlag;
139 panel.fullscreenMode = data.fullscreenFlag;
140+ if (data.alreadyOpen) {
141+ panel.indicators.show();
142+ tryCompare(panel.indicators, "fullyOpened", true);
143+ }
138
144
139 var indicatorRow = findChild(panel.indicators, "indicatorRow");
145 var indicatorRow = findChild(panel.indicators, "indicatorRow");
140 verify(indicatorRow != undefined);
146 verify(indicatorRow != undefined);
@@ -186,7 +192,9 @@ Item {
186 compare(menuContent.currentMenuIndex, i, "Menu conetent should be enabled for item at position " + i);
192 compare(menuContent.currentMenuIndex, i, "Menu conetent should be enabled for item at position " + i);
187
193
188 // init for next indicatorItem
194 // init for next indicatorItem
195+ if (!data.alreadyOpen) {
189− init();
196+ init();
197+ }
190 }
198 }
191 }
199 }
192
200
tests/qmltests/tst_Shell.qml+74−13
@@ -55,19 +55,45 @@ Item {
55 when: windowShown
55 when: windowShown
56
56
57 function initTestCase() {
57 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;
59
74
60− // Ensure DashHome is loaded before continuing
75+ var dashHome = findChild(shell, "DashHome");
76+ ok &= dashHome !== undefined;
77+
61− var dashContentList = findChild(shell, "dashContentList");
78+ var greeter = findChild(shell, "greeter");
62− waitForRendering(dashContentList);
79+ ok &= greeter !== undefined;
63− var homeLoader = findChild(dashContentList, "home.scope loader");
80+
64− verify(homeLoader);
81+ var launcherPanel = findChild(shell, "launcherPanel");
65− tryCompareFunction(function() {return homeLoader.item !== undefined;}, true);
82+ ok &= launcherPanel !== undefined;
66
83
67− // FIXME: Desperate measure to ensure Jenkins has the scene graph fully loaded
84+ attempts++;
68− // before it calls the test functions (otherwise findChild calls will fail).
85+ if (!ok) {
69− // The code above just didn't solve it.
86+ console.log("Attempt " + attempts + " failed. Waiting a bit before trying again.");
70− wait(2000);
87+ // wait a bit before retrying
88+ wait(100);
89+ } else {
90+ console.log("All seem fine after " + attempts + " attempts.");
91+ }
92+ } while (!ok && attempts <= maxAttempts);
93+
94+ verify(ok);
95+
96+ swipeAwayGreeter();
71 }
97 }
72
98
73 function cleanup() {
99 function cleanup() {
@@ -297,6 +323,10 @@ Item {
297
323
298 waitUntilApplicationWindowIsFullyVisible();
324 waitUntilApplicationWindowIsFullyVisible();
299
325
326+ // Dragging launcher into view with a little bit of gap (units.gu(1)) should switch to Apps scope
327+ dragLauncherIntoView();
328+ verify(itemIsOnScreen(dashApps));
329+
300 // Minimize the application we just launched
330 // Minimize the application we just launched
301 swipeFromLeftEdge(units.gu(27));
331 swipeFromLeftEdge(units.gu(27));
302
332
@@ -437,7 +467,7 @@ Item {
437 } while (!isStill);
467 } while (!isStill);
438 }
468 }
439
469
440− function test_wallpaper_data() {
470+ function test_background_data() {
441 return [
471 return [
442 {tag: "red", url: "tests/data/unity/backgrounds/red.png", expectedUrl: "tests/data/unity/backgrounds/red.png"},
472 {tag: "red", url: "tests/data/unity/backgrounds/red.png", expectedUrl: "tests/data/unity/backgrounds/red.png"},
443 {tag: "blue", url: "tests/data/unity/backgrounds/blue.png", expectedUrl: "tests/data/unity/backgrounds/blue.png"},
473 {tag: "blue", url: "tests/data/unity/backgrounds/blue.png", expectedUrl: "tests/data/unity/backgrounds/blue.png"},
@@ -446,13 +476,21 @@ Item {
446 ]
476 ]
447 }
477 }
448
478
449− function test_wallpaper(data) {
479+ function test_background(data) {
450 var backgroundImage = findChild(shell, "backgroundImage")
480 var backgroundImage = findChild(shell, "backgroundImage")
451 GSettingsController.setPictureUri(data.url)
481 GSettingsController.setPictureUri(data.url)
452 tryCompareFunction(function() { return backgroundImage.source.toString().indexOf(data.expectedUrl) !== -1; }, true)
482 tryCompareFunction(function() { return backgroundImage.source.toString().indexOf(data.expectedUrl) !== -1; }, true)
453 tryCompare(backgroundImage, "status", Image.Ready)
483 tryCompare(backgroundImage, "status", Image.Ready)
454 }
484 }
455
485
486+ function test_lockscreen_background() {
487+ var backgroundImage = findChild(shell, "backgroundImage")
488+ var lockscreen = findChild(shell, "lockscreen")
489+ var lockscreenBackground = findChild(lockscreen, "lockscreenBackground")
490+ var lockscreenBackgroundMapped = lockscreenBackground.mapToItem(shell, 0, 0)
491+ compare(backgroundImage.y, lockscreenBackgroundMapped.y)
492+ }
493+
456 function test_DashShown_data() {
494 function test_DashShown_data() {
457 return [
495 return [
458 {tag: "in focus", greeter: false, app: false, launcher: false, indicators: false, expectedShown: true},
496 {tag: "in focus", greeter: false, app: false, launcher: false, indicators: false, expectedShown: true},
@@ -488,5 +526,28 @@ Item {
488 var dash = findChild(shell, "dash");
526 var dash = findChild(shell, "dash");
489 tryCompare(dash, "shown", data.expectedShown);
527 tryCompare(dash, "shown", data.expectedShown);
490 }
528 }
529+
530+ function test_searchIndicatorHidesOnAppFocus() {
531+ var searchIndicator = findChild(shell, "container")
532+ tryCompare(searchIndicator, "opacity", 1)
533+ dragLauncherIntoView();
534+
535+ // Launch an app from the launcher
536+ tapOnAppIconInLauncher();
537+ waitUntilApplicationWindowIsFullyVisible();
538+
539+ tryCompare(searchIndicator, "opacity", 0);
540+ }
541+
542+ function test_searchIndicatorHidesOnGreeterShown() {
543+ var searchIndicator = findChild(shell, "container")
544+ var greeter = findChild(shell, "greeter");
545+
546+ tryCompare(searchIndicator, "opacity", 1)
547+
548+ greeter.show()
549+ tryCompare(greeter, "shown", true)
550+ tryCompare(searchIndicator, "opacity", 0)
551+ }
491 }
552 }
492}
553}
tests/utils/modules/Unity/Test/UnityTestCase.qml+36
@@ -14,6 +14,7 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17+import QtQuick 2.0
17import QtTest 1.0
18import QtTest 1.0
18import Ubuntu.Components 0.1
19import Ubuntu.Components 0.1
19import Unity.Test 0.1 as UT
20import Unity.Test 0.1 as UT
@@ -213,6 +214,8 @@ TestCase {
213
214
214 // speed is in pixels/second
215 // speed is in pixels/second
215 function touchFlick(item, x, y, toX, toY, beginTouch, endTouch, speed, iterations) {
216 function touchFlick(item, x, y, toX, toY, beginTouch, endTouch, speed, iterations) {
217+ // Make sure the item is rendered
218+ waitForRendering(item);
216
219
217 // Default to true for beginTouch if not present
220 // Default to true for beginTouch if not present
218 beginTouch = (beginTouch !== undefined) ? beginTouch : true
221 beginTouch = (beginTouch !== undefined) ? beginTouch : true
@@ -297,4 +300,37 @@ TestCase {
297 event.release(0 /* touchId */, x, y)
300 event.release(0 /* touchId */, x, y)
298 event.commit()
301 event.commit()
299 }
302 }
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+ }
300}
336}