on xenial help sign in
Merge trunk
40c7650Michal Hruby
.bazaar/plugins/makecheck_unity_phablet.py+15−6
@@ -23,12 +23,21 @@ def execute_makecheck(local_branch, master_branch, old_revision_number, old_revi
23
23
24 os.chdir(local_path_from_url(master_branch.base))
24 os.chdir(local_path_from_url(master_branch.base))
25
25
26− print "Executing 'make check'.."
26+ print "Executing 'make -C builddir test'.."
27+ os.environ['CTEST_OUTPUT_ON_FAILURE'] = "1"
27− if (subprocess.call("make check", shell=True) != 0):
28+ if (subprocess.call("make -C builddir test", shell=True) != 0):
28− raise errors.BzrError("Unit tests failed, fix them before committing!")
29
29
30− print "Executing 'make qmluitests'.."
30+ print("\n\n*** Warning ***\n\nBasic tests failed. This commit will not pass continuous integration.")
31− if (subprocess.call("make qmluitests", shell=True) != 0):
31+
32− raise errors.BzrError("QML UI tests failed, fix them before committing!")
32+ branch = local_branch or master_branch
33+ revision = branch.repository.get_revision(future_revision_id)
34+ msg_file = open('message.txt', 'w')
35+ msg_file.write(revision.message)
36+ msg_file.close()
37+
38+ print("\n\nSaved commit message to $SRC_DIR/message.txt.")
39+ print("You can uncommit this revision, fix the tests and reuse your message running:\n\nbzr commit -F message.txt\n\n")
40+ elif os.path.isfile("message.txt"):
41+ os.remove("message.txt")
33
42
34branch.Branch.hooks.install_named_hook('pre_commit', execute_makecheck, 'make check pre-commit')
43branch.Branch.hooks.install_named_hook('pre_commit', execute_makecheck, 'make check pre-commit')
.bzrignore+1
@@ -7,3 +7,4 @@
7/.cproject
7/.cproject
8/.settings
8/.settings
9/.pydevproject
9/.pydevproject
10+message.txt
Bottombar/Bottombar.qml+1−8
@@ -64,7 +64,7 @@ Item {
64 onShownChanged: bottomBarVisibilityCommunicatorShell.forceHidden = theHud.shown
64 onShownChanged: bottomBarVisibilityCommunicatorShell.forceHidden = theHud.shown
65 }
65 }
66
66
67− DirectionalDragArea {
67+ EdgeDragArea {
68 id: dragArea
68 id: dragArea
69 width: parent.width
69 width: parent.width
70 height: distanceThreshold
70 height: distanceThreshold
@@ -73,13 +73,6 @@ Item {
73 enabled: !theHud.shown && bottombar.enabled && applicationIsOnForeground
73 enabled: !theHud.shown && bottombar.enabled && applicationIsOnForeground
74 direction: Direction.Upwards
74 direction: Direction.Upwards
75
75
76− // values to be tweaked and later removed from here and set in stone as defaults
77− // once we are confident it's all good.
78− maxDeviation: units.gu(1)
79− wideningAngle: 30
80− distanceThreshold: units.gu(3)
81− minSpeed: units.gu(5)
82−
83 property int previousStatus: -1
76 property int previousStatus: -1
84 property real touchStartX: -1
77 property real touchStartX: -1
85
78
CODING+75−29
@@ -1,43 +1,64 @@
1Building Unity 8
1Building Unity 8
2================
2================
3
3
4+Only Ubuntu 13.10 (saucy) is supported as a developement environment.
5+
4download source
6download source
5---------------
7---------------
6−- the build requires some additional dependencies, so create the parent folder to not pollute your setup
8+- create a parent folder to not pollute your setup. so that you can have different unity
9+ branches there (trunk, WIP etc)
10+
7− $ mkdir ~/unity
11+ $ mkdir ~/unity8
8
12
9- fetch Unity 8 source
13- fetch Unity 8 source
10 $ sudo apt-get install bzr
14 $ sudo apt-get install bzr
11− $ bzr branch lp:unity/8.0 ~/unity/unity8
15+ $ bzr branch lp:unity8 ~/unity8/trunk
12− $ cd ~/unity/unity8
16+ $ cd ~/unity8/trunk
17+
18+install dependencies
19+--------------------
20+If its your first time, install build dependencies
21+
22+$ cd ~/unity8/trunk
23+$ ./build --setup
13
24
14−build dependencies
15−------------------
16−If its your first time, download & build deps
17−$ ./build -s
18 this will:
25 this will:
26+ - add the following PPA's
27+ - ppa:phablet-team/desktop-deps
19− - add ppa:phablet-team/desktop-deps, ppa:canonical-qt5-edgers/qt5-proper, ppa:ubuntu-sdk-team
28+ - ppa:canonical-qt5-edgers/qt5-proper
20− - build and install lp:libunity/phablet, lp:unity/phablet-mods, lp:hud/phablet locally
29+ - ppa:ubuntu-sdk-team
21− - install build dependencies
30+ - install the required dependencies to build, as well as run on the desktop
31+ - it should also install unity-scope-home and unity-lens-application which
32+ are technically "recommends", not strict dependencies
33+
34+Note, once the PPA's are added, the script runs apt-get update, if you have
35+any failures associated with it, the build script will bail out of the setup
36+and fail to install all the required dependencies.
37+
22
38
23build Unity 8
39build Unity 8
24-------------
40-------------
25−$ ./build
26
41
27−subsequent updates of the dependencies
42+$ cd ~/unity8/trunk
28−--------------------------------------
43+$ ./build
29−$ ./build_unity -u
30−$ ./build_unity
31
44
45+You may also rebuild with the -c for clean, which just deletes the build
46+directory.
32
47
33Running Unity 8 on your desktop
48Running Unity 8 on your desktop
34===============================
49===============================
35
50
36run the Unity 8 shell
51run the Unity 8 shell
37---------------------
52---------------------
38−$ cd ~/unity/unity8
53+$ cd ~/unity8/trunk
39$ ./run
54$ ./run
40
55
56+Options can be passed to test the lock screen
57+$ ./run -p OR -k
58+
59+-p is for pin lock, for which the default prompt answer is "1234"
60+-k is for keylock passphrase, for which the default prompt answer is "password"
61+
41Notes
62Notes
42-----
63-----
43- to navigate, utilize the mouse left button as you would your finger
64- to navigate, utilize the mouse left button as you would your finger
@@ -45,17 +66,29 @@ Notes
45 put the *.mo files into correct structure. We'll look for a better solution
66 put the *.mo files into correct structure. We'll look for a better solution
46 later.
67 later.
47 $ cd builddir; make install
68 $ cd builddir; make install
69+- if you wish to populate contacts
70+ $ sudo apt-get install gir1.2-ebook-1.2
71+ $ manage-address-book.py create
72+ this will:
73+ - Create an EDS address book
74+ - Populate the address book with sample data
48
75
49Running Unity 8 on devices
76Running Unity 8 on devices
50==========================
77==========================
51- Ubuntu Touch builds are currently only available in 13.10 flavour
78- Ubuntu Touch builds are currently only available in 13.10 flavour
52−- supported hardware should match one those listed here https://wiki.ubuntu.com/Touch/Devices#Running_fine
79+- supported hardware should match one those listed here
80+ https://wiki.ubuntu.com/Touch/Devices#Running_fine
53−- follow the Ubuntu Touch install instructions for your chosen device https://wiki.ubuntu.com/Touch/Install
81+- follow the Ubuntu Touch install instructions for your chosen device
82+ https://wiki.ubuntu.com/Touch/Install
54- make sure your device is connected to a WiFi network
83- make sure your device is connected to a WiFi network
84+- If you haven’t already or if you’ve just freshly flashed your device
85+ make sure you run phablet-network-setup which will allow package updates to
86+ the device
55−- also make sure you have your SSH key in ~/.ssh/id_rsa.pub (or install one on the device yourself)
87+- also make sure you have your SSH key in ~/.ssh/id_rsa.pub (or install one
56−
88+ on the device yourself)
89+
57−$ cd ~/unity/unity8
90+$ cd ~/unity/trunk
58−$ ./run_on_device -s
91+$ ./run_on_device --setup
59 this will:
92 this will:
60 - install your public SSH key on the device
93 - install your public SSH key on the device
61 - add ppa:canonical-qt5-edgers/qt5-proper and ppa:phablet-team
94 - add ppa:canonical-qt5-edgers/qt5-proper and ppa:phablet-team
@@ -67,19 +100,27 @@ $ ./run_on_device
67 - build on the device
100 - build on the device
68 - replace the running shell
101 - replace the running shell
69
102
103+Options can be passed to test the lock screen
104+$ ./run_on_device -p OR -k
105+
106+-p is for pin lock, for which the default prompt answer is "1234"
107+-k is for keylock passphrase, for which the default prompt answer is "password"
108+
70Notes
109Notes
71-----
110-----
72- using adb over TCP has some advantages, Google will be of help here
111- using adb over TCP has some advantages, Google will be of help here
73 - TL;DR: `adb tcpip 5555; adb connect $your_device_ip`
112 - TL;DR: `adb tcpip 5555; adb connect $your_device_ip`
74 - you can persist the above via `adb shell setprop persist.adb.tcp.port 5555`
113 - you can persist the above via `adb shell setprop persist.adb.tcp.port 5555`
75 - it's unsafe - anyone can connect to your device
114 - it's unsafe - anyone can connect to your device
76− - with TCP the Nexus 10 doesn't drop the adb connection when locking the screen
115+ - with TCP the Nexus 10 doesn't drop the adb connection when locking
116+ the screen
77−- exporting ANDROID_SERIAL=$your_device_serial or ANDROID_SERIAL=$your_device_ip:5555
117+- exporting ANDROID_SERIAL=$your_device_serial or
78− will make adb not complain about multiple devices
118+ ANDROID_SERIAL=$your_device_ip:5555 will make adb not complain about
119+ multiple devices
79- you can export TARGET_IP=$your_device_ip TARGET_SSH_PORT=22 for run_on_device
120- you can export TARGET_IP=$your_device_ip TARGET_SSH_PORT=22 for run_on_device
80 to not use adb forwarding - useful if you use multiple devices
121 to not use adb forwarding - useful if you use multiple devices
81−- using Ninja (package ninja-build - run_on_device -s installs this now) will improve
122+- using Ninja (package ninja-build - run_on_device -s installs this now)
82− build times (especially in the nothing-to-build case)
123+ will improve build times (especially in the nothing-to-build case)
83
124
84
125
85Coding guidelines
126Coding guidelines
@@ -90,4 +131,9 @@ https://launchpad.net/canonical-client-development-guidelines
90
131
91Development Environment
132Development Environment
92=======================
133=======================
93−QtCreator (available via the Software Center) is the best IDE to hack on Unity 8.
134+QtCreator (available via the Software Center) is the best IDE to hack on
135+Unity 8.
136+
137+If using VIM, make sure you install some syntax highlighting for QML, like
138+https://github.com/peterhoeg/vim-qml
139+
Components/Carousel.qml+2
@@ -24,6 +24,8 @@ import "carousel.js" as CarouselJS
24Item {
24Item {
25 id: carousel
25 id: carousel
26
26
27+ clip: true // Don't leak horizontally to other dashes
28+
27 /// The component to be used as delegate. This component has to be derived from BaseCarouselDelegate
29 /// The component to be used as delegate. This component has to be derived from BaseCarouselDelegate
28 property Component itemComponent
30 property Component itemComponent
29 /// Model for the Carousel, which has to be a model usable by a ListView
31 /// Model for the Carousel, which has to be a model usable by a ListView
Components/DragHandle.qmlnew file+208
@@ -0,0 +1,208 @@
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 Ubuntu.Gestures 0.1
20+import "Math.js" as MathLocal
21+
22+/*
23+ Put a DragHandle inside a Showable to enable the user to drag it from that handle.
24+ Main use case is to drag fullscreen Showables into the screen or off the screen.
25+
26+ This example shows a DragHandle placed on the right corner of a Showable, used
27+ to slide it away, off the screen.
28+
29+ Showable {
30+ x: 0
31+ y: 0
32+ width: ... // screen width
33+ height: ... // screen height
34+ shown: true
35+ ...
36+ DragHandle {
37+ anchors.right: parent.right
38+ anchors.top: parent.top
39+ anchors.bottom: parent.bottom
40+ width: units.gu(2)
41+
42+ direction: DirectionalDragArea::Leftwards
43+ }
44+ }
45+
46+ */
47+EdgeDragArea {
48+ id: dragArea
49+ objectName: "dragHandle"
50+
51+ property bool stretch: false
52+
53+ property alias autoCompleteDragThreshold: dragEvaluator.dragThreshold
54+
55+ // How far you can drag
56+ property real maxTotalDragDistance: {
57+ if (stretch) {
58+ 0; // not enough context information to set a sensible default
59+ } else {
60+ Direction.isHorizontal(direction) ? parent.width : parent.height;
61+ }
62+ }
63+
64+ property real hintDisplacement: 0
65+ SmoothedAnimation {
66+ id: hintingAnimation
67+ target: hintingAnimation
68+ property: "targetValue"
69+ duration: 150
70+ velocity: -1
71+ to: Direction.isPositive(direction) ? d.startValue + hintDisplacement
72+ : d.startValue - hintDisplacement
73+ property real targetValue
74+ onTargetValueChanged: {
75+ if (!running) {
76+ return;
77+ }
78+
79+ if (Direction.isPositive(direction)) {
80+ if (parent[d.targetProp] < targetValue) {
81+ parent[d.targetProp] = targetValue;
82+ }
83+ } else {
84+ if (parent[d.targetProp] > targetValue) {
85+ parent[d.targetProp] = targetValue;
86+ }
87+ }
88+ }
89+ }
90+
91+ // Private stuff
92+ QtObject {
93+ id: d
94+ property var previousStatus: undefined
95+ property real startValue
96+ property real minValue: Direction.isPositive(direction) ? startValue
97+ : startValue - maxTotalDragDistance
98+ property real maxValue: Direction.isPositive(direction) ? startValue + maxTotalDragDistance
99+ : startValue
100+
101+ property var dragParent: dragArea.parent
102+
103+ // The property of DragHandle's parent that will be modified
104+ property string targetProp: {
105+ if (stretch) {
106+ Direction.isHorizontal(direction) ? "width" : "height";
107+ } else {
108+ Direction.isHorizontal(direction) ? "x" : "y";
109+ }
110+ }
111+
112+ function limitMovement(step) {
113+ var targetValue = MathLocal.clamp(dragParent[targetProp] + step, minValue, maxValue);
114+ var step = targetValue - dragParent[targetProp];
115+
116+ if (hintDisplacement == 0) {
117+ return step;
118+ }
119+
120+ // we should not go behind hintingAnimation's current value
121+ if (Direction.isPositive(direction)) {
122+ if (dragParent[targetProp] + step < hintingAnimation.targetValue) {
123+ step = hintingAnimation.targetValue - dragParent[targetProp];
124+ }
125+ } else {
126+ if (dragParent[targetProp] + step > hintingAnimation.targetValue) {
127+ step = hintingAnimation.targetValue - dragParent[targetProp];
128+ }
129+ }
130+
131+ return step;
132+ }
133+
134+ function onFinishedRecognizedGesture() {
135+ if (dragEvaluator.shouldAutoComplete()) {
136+ completeDrag();
137+ } else {
138+ rollbackDrag();
139+ }
140+ }
141+
142+ function completeDrag() {
143+ if (dragParent.shown) {
144+ dragParent.hide();
145+ } else {
146+ dragParent.show();
147+ }
148+ }
149+
150+ function rollbackDrag() {
151+ if (dragParent.shown) {
152+ dragParent.show();
153+ } else {
154+ dragParent.hide();
155+ }
156+ }
157+ }
158+
159+ property alias edgeDragEvaluator: dragEvaluator
160+
161+ EdgeDragEvaluator {
162+ objectName: "edgeDragEvaluator"
163+ id: dragEvaluator
164+ trackedPosition: sceneDistance
165+ maxDragDistance: maxTotalDragDistance
166+ direction: dragArea.direction
167+ }
168+
169+ onDistanceChanged: {
170+ if (status === DirectionalDragArea.Recognized) {
171+ // don't go the whole distance in order to smooth out the movement
172+ var step = distance * 0.3;
173+
174+ step = d.limitMovement(step);
175+
176+ parent[d.targetProp] += step;
177+ }
178+ }
179+
180+ onDraggingChanged: {
181+ if (dragging) {
182+ if (hintDisplacement > 0) {
183+ hintingAnimation.targetValue = d.startValue;
184+ hintingAnimation.start();
185+ }
186+ } else {
187+ hintingAnimation.stop();
188+ }
189+ }
190+
191+ onStatusChanged: {
192+ if (status === DirectionalDragArea.WaitingForTouch) {
193+ if (d.previousStatus === DirectionalDragArea.Recognized) {
194+ d.onFinishedRecognizedGesture();
195+ }
196+ d.startValue = parent[d.targetProp];
197+ }
198+
199+ if (d.previousStatus === DirectionalDragArea.WaitingForTouch ||
200+ d.previousStatus === undefined) {
201+ dragEvaluator.reset();
202+ d.startValue = parent[d.targetProp];
203+ }
204+
205+ d.previousStatus = status;
206+ }
207+
208+}
Components/EdgeDragArea.qmlnew file+36
@@ -0,0 +1,36 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import Ubuntu.Gestures 0.1
20+
21+/*
22+ A DirectionalDragArea wrapper that provides some well-chosen defaults
23+ for its gesture recognition parameters.
24+*/
25+DirectionalDragArea {
26+
27+ // TODO: Re-evaluate those or even the recognition heuristics itself once
28+ // we have gesture cancelling/forwarding in place.
29+ //
30+ // The idea here is that it's better having lax rules than false negatives.
31+ // False negatives are very frustrating to the user.
32+ maxDeviation: units.gu(3)
33+ wideningAngle: 50
34+ distanceThreshold: units.gu(1.5)
35+ minSpeed: units.gu(0) // some people were getting false negatives with it enabled.
36+}
Components/EdgeDragEvaluator.qmlnew file+88
@@ -0,0 +1,88 @@
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 Ubuntu.Gestures 0.1
20+
21+/*
22+ Evaluates end velocity (velocity at the moment the gesture ends) and travelled
23+ distance (delta between finger down and finger up positions) to determine
24+ whether the drag should continue by itself towards completion (auto-complete)
25+ after the finger has left the touchscreen.
26+ */
27+AxisVelocityCalculator {
28+
29+ // How far the drag can go, or should go to achieve completion.
30+ property real maxDragDistance
31+
32+ // Ending a drag at any point before this threshold will need some positive velocity
33+ // (i.e., towards the set direction) to get auto-completion (e.g. to get show()
34+ // called for a hidden Showable) and ending a drag at any point after this
35+ // threshold will need some negative velocity to avoid auto-completion.
36+ property real dragThreshold: maxDragDistance / 2
37+
38+ property real minDragDistance: maxDragDistance * 0.1
39+
40+ // Speed needed to get auto-completion for an hypothetical flick of length zero.
41+ //
42+ // This requirement is gradually reduced as flicks gets longer until it reaches
43+ // a value of zero for flicks of dragThreshold lenght.
44+ //
45+ // in pixels per second
46+ property real speedThreshold: units.gu(70)
47+
48+ property int direction
49+
50+ property real velocity
51+ property real minVelocity
52+
53+ // Returns whether the drag should continue by itself until completed.
54+ function shouldAutoComplete() {
55+ var deltaPos = trackedPosition - __startPosition;
56+ if (Math.abs(deltaPos) < minDragDistance) {
57+ velocity = 0;
58+ minVelocity = 0;
59+ return false;
60+ }
61+
62+ minVelocity = __calculateMinimumVelocityForAutoCompletion(deltaPos);
63+ velocity = calculate();
64+
65+ if (Direction.isPositive(direction) && (velocity >= minVelocity)
66+ || !Direction.isPositive(direction) && (velocity <= minVelocity)) {
67+ return true;
68+ } else {
69+ return false;
70+ }
71+ }
72+
73+ property real __startPosition
74+
75+ // speedThreshold in pixels per millisecond
76+ property real __speedThresholdMs: speedThreshold / 1000.0
77+
78+ // Minimum velocity when a drag total distance is zero
79+ property real __v0: Direction.isPositive(direction) ? __speedThresholdMs : - __speedThresholdMs
80+
81+ function __calculateMinimumVelocityForAutoCompletion(distance) {
82+ return __v0 - ((__speedThresholdMs / dragThreshold) * distance);
83+ }
84+
85+ function reset() {
86+ __startPosition = trackedPosition;
87+ }
88+}
Components/FilterGrid.qml+1−1
@@ -108,7 +108,7 @@ Item {
108
108
109 anchors.fill: parent
109 anchors.fill: parent
110 radius: "small"
110 radius: "small"
111− borderSource: ItemStyle.style.borderPressed
111+ borderSource: "radius_pressed.sci"
112 opacity: button.pressed ? 1.0 : 0.0
112 opacity: button.pressed ? 1.0 : 0.0
113 Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.OutQuint } }
113 Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.OutQuint } }
114 }
114 }
Components/ListItems/Base.qml+19−21
@@ -54,35 +54,33 @@ AbstractButton {
54 */
54 */
55 function __showDivider() {
55 function __showDivider() {
56 // if we're not in ListView, always show a thin dividing line at the bottom
56 // if we're not in ListView, always show a thin dividing line at the bottom
57− if (ListView.view !== null) {
57+ var model = null;
58−
58+ if (typeof ListViewWithPageHeader !== 'undefined') {
59− // if we're last item in ListView don't show divider
59+ if (typeof ListViewWithPageHeader.model !== 'undefined') {
60− if (index === ListView.view.model.count - 1) return false;
60+ model = ListViewWithPageHeader.model;
61+ }
62+ } else if (ListView.view !== null) {
63+ model = ListView.view.model;
61 }
64 }
65+ // if we're last item in ListView don't show divider
66+ if (model && index === model.count - 1) return false;
67+
62 return true;
68 return true;
63 }
69 }
64
70
65− property bool __clippingRequired: ListView.view !== null
71+ /* Relevant really only for ListViewWithPageHeader case: specify how many pixels we can overlap with the section header */
66− && ListView.view.section.labelPositioning & ViewSection.CurrentLabelAtStart
72+ readonly property int allowedOverlap: units.dp(1)
67−
68− property real __yPositionRelativeToListView: ListView.view ? y - ListView.view.contentY : y
69
73
70 property real __heightToClip: {
74 property real __heightToClip: {
71 // Check this is in position where clipping is needed
75 // Check this is in position where clipping is needed
72− if (__clippingRequired && __yPositionRelativeToListView <= __sectionDelegateHeight
76+ if (typeof ListViewWithPageHeader !== 'undefined') {
73− && __yPositionRelativeToListView > -height) {
77+ if (typeof heightToClip !== 'undefined') {
74− return Math.min(__sectionDelegateHeight - __yPositionRelativeToListView, height);
78+ if (heightToClip >= allowedOverlap) {
75− } else {
79+ return heightToClip - allowedOverlap;
76− return 0;
80+ }
77− }
81+ }
78− }
79−
80− property int __sectionDelegateHeight: {
81− if (__clippingRequired && ListView.view.hasOwnProperty("__sectionDelegateHeight")) {
82− return ListView.view.__sectionDelegateHeight;
83− } else {
84− return 0;
85 }
82 }
83+ return 0;
86 }
84 }
87
85
88 /*!
86 /*!
Components/ListItems/Header.qml−6
@@ -25,12 +25,6 @@ Item {
25 */
25 */
26 property alias text: label.text
26 property alias text: label.text
27
27
28− /* When this header is used in a ListViewWithPageHeader with CurrentLabelAtStart mode, to stop
29− the list's delegates contents being visible through this header, they clip themselves
30− depending on their position. However to allow delegates underlap the bottom X pixels of this
31− header (so delegate appears through ThinDivider say) we set an offset property here. */
32− readonly property int bottomBorderAllowedOverlap: bottomBorder.allowedBottomOverlap
33−
34 height: units.gu(4.5)
28 height: units.gu(4.5)
35
29
36 Item {
30 Item {
Components/ListItems/ThinDivider.qml−4
@@ -23,9 +23,5 @@ Image {
23 }
23 }
24 height: (visible) ? units.dp(2) : 0
24 height: (visible) ? units.dp(2) : 0
25
25
26− /* Relevant really only for ListViewWithPageHeader with Base delegates: should this image
27− be overlapping content, specify how many pixels from the bottom should be transparent */
28− readonly property int allowedBottomOverlap: units.dp(1)
29−
30 source: "graphics/ListItemDividerHorizontal.png"
26 source: "graphics/ListItemDividerHorizontal.png"
31}
27}
Components/ListViewWithPageHeader.qmldeleted−189
@@ -1,189 +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 "Math.js" as MathLocal
19−
20−Item {
21− id: root
22− property Item pageHeader: null
23− property Component sectionDelegate: null
24− property string sectionProperty: ""
25− property alias model: listView.model
26− property alias delegate: listView.delegate
27− property ListView view: listView
28− property alias moving: flicker.moving
29− property alias atYEnd: flicker.atYEnd
30− property bool clipListView: true
31−
32− readonly property real __headerHeight: (pageHeader) ? pageHeader.implicitHeight : 0
33− property real __headerVisibleHeight: __headerHeight
34− readonly property real __overshootHeight: (flicker.contentY < 0) ? -flicker.contentY : 0
35−
36−
37− // TODO move to AnimationController
38− ParallelAnimation {
39− id: headerAnimation
40− property real targetContentY
41− NumberAnimation {
42− target: root
43− property: "__headerVisibleHeight"
44− to: root.__headerHeight
45− duration: 200
46− easing.type: Easing.OutQuad
47− }
48− NumberAnimation {
49− target: listView
50− property: "contentY"
51− to: headerAnimation.targetContentY
52− duration: 200
53− easing.type: Easing.OutQuad
54− }
55− }
56−
57− function positionAtBeginning() {
58− __headerVisibleHeight = __headerHeight
59− flicker.contentY = 0
60− }
61−
62− function showHeader() {
63− headerAnimation.targetContentY = listView.contentY + (__headerHeight - __headerVisibleHeight)
64− headerAnimation.start()
65− }
66−
67− function flick(xVelocity, yVelocity) {
68− flicker.flick(xVelocity, yVelocity);
69− }
70−
71− onPageHeaderChanged: {
72− pageHeader.parent = pageHeaderContainer;
73− pageHeader.anchors.fill = pageHeaderContainer;
74− }
75−
76− Item {
77− id: pageHeaderClipper
78− parent: flicker // parent to Flickable so mouse click events passed through to the header component
79− anchors {
80− top: parent.top
81− left: parent.left
82− right: parent.right
83− }
84− height: __headerVisibleHeight + __overshootHeight
85−
86− Item {
87− id: pageHeaderContainer
88− anchors {
89− left: parent.left
90− right: parent.right
91− bottom: parent.bottom
92− }
93− height: __headerHeight + __overshootHeight
94− }
95− }
96−
97− ListView {
98− id: listView
99− parent: flicker // parent to Flickable so mouse click events passed through to List delegates
100− anchors {
101− left: parent.left
102− right: parent.right
103− top: parent.top
104− topMargin: __headerVisibleHeight
105− }
106− height: root.height
107−
108− // FIXME scrolling workaround, see below
109− cacheBuffer: height*10
110−
111− section.property: sectionProperty
112− section.criteria: ViewSection.FullString
113− section.labelPositioning: ViewSection.InlineLabels | ViewSection.CurrentLabelAtStart
114− section.delegate: sectionDelegate
115−
116− interactive: false
117− clip: root.clipListView
118−
119− property int __sectionDelegateHeight: __getHeight(section.delegate)
120− function __getHeight(component) {
121− // want height (minus allowed overlap) of the section delegate as is needed for clipping
122− if (component === null) return 0;
123− var object = component.createObject(); //FIXME: throws 'section' not defined error
124− var value = object.height - object.bottomBorderAllowedOverlap;
125− object.destroy();
126− return value;
127− }
128−
129− property real previousOriginY: 0
130− onOriginYChanged: {
131− var deltaOriginY = originY - previousOriginY;
132− previousOriginY = originY;
133− /* When originY changes, it causes the top of the flicker and the top of the list to fall
134− out of sync - and thus the contentY positioning will be broken. To correct for this we
135− manually change the flickable's contentY here */
136− flicker.contentY -= deltaOriginY;
137− }
138−
139− /* For case when list content greater than container height and list scrolled down so header
140− hidden. If content shrinks to be smaller than the container height, we want the header to
141− re-appear */
142− property real __previousContentHeight: 0
143− onContentHeightChanged: {
144− var deltaContentHeight = contentHeight - __previousContentHeight;
145− __previousContentHeight = contentHeight;
146− if (contentHeight < height && deltaContentHeight < 0 && __headerVisibleHeight < height - contentHeight) {
147− __headerVisibleHeight = Math.min(height - contentHeight, __headerHeight);
148− }
149− }
150− }
151−
152− Flickable {
153− id: flicker
154− anchors.fill: parent
155− contentHeight: listView.contentHeight + __headerHeight
156− maximumFlickVelocity: height * 10
157− flickDeceleration: height * 2
158− onContentYChanged: {
159− var deltaContentY = contentY - __previousContentY;
160− __previousContentY = contentY;
161−
162− // first decide if movement will prompt the page header to change height
163− if ((deltaContentY < 0 && __headerVisibleHeight >= 0) ||
164− (deltaContentY > 0 && __headerVisibleHeight <= __headerHeight)) {
165−
166− // calculate header height - but prevent bounce from changing it
167− if (contentY > 0 && contentY < contentHeight - height) {
168− __headerVisibleHeight = MathLocal.clamp(__headerVisibleHeight - deltaContentY, 0, __headerHeight);
169− }
170− }
171−
172− // now we move list position, taking into account page header height
173−
174− // BUG: With section headers enabled, the values of originY and contentY appear not
175− // correct at the exact point originY changes. originY changes when the ListView
176− // deletes/creates hidden delegates which are above the visible delegates.
177− // As a result of this bug, you experience jittering scrolling when rapidly moving
178− // around in large lists. See https://bugreports.qt-project.org/browse/QTBUG-27997
179− // A workaround is to use a large enough cacheBuffer to prevent deletions/creations
180− // so effectively originY is always zero.
181− var newContentY = flicker.contentY + listView.originY - __headerHeight + __headerVisibleHeight
182− if (newContentY < listView.contentHeight) {
183− listView.contentY = newContentY;
184− }
185− }
186−
187− property real __previousContentY: 0
188− }
189−}
Components/PageHeader.qml+2−2
@@ -149,7 +149,7 @@ Item {
149
149
150 primaryItem: Button {
150 primaryItem: Button {
151 enabled: searchField.text != ""
151 enabled: searchField.text != ""
152− ItemStyle.class: "transparent-button"
152+ color: "transparent"
153 onClicked: {
153 onClicked: {
154 if (searchField.text != "") {
154 if (searchField.text != "") {
155 searchHistory.addQuery(searchField.text)
155 searchHistory.addQuery(searchField.text)
@@ -272,7 +272,7 @@ Item {
272 // FIXME: this should go into the first item below, but enable: false
272 // FIXME: this should go into the first item below, but enable: false
273 // prevents mouse events propagation
273 // prevents mouse events propagation
274 Button {
274 Button {
275− ItemStyle.class: "transparent-button"
275+ color: "transparent"
276 anchors {
276 anchors {
277 top: parent.top
277 top: parent.top
278 right: parent.right
278 right: parent.right
Components/Stage.qml+8−10
@@ -416,12 +416,14 @@ Showable {
416 }
416 }
417 }
417 }
418
418
419− AxisVelocityCalculator {
419+ EdgeDragEvaluator {
420− id: dragVelocityCalculator
420+ id: dragEvaluator
421− trackedPosition: rightEdgeDraggingArea.distance
421+ trackedPosition: rightEdgeDraggingArea.touchX
422+ direction: rightEdgeDraggingArea.direction
423+ maxDragDistance: stage.width
422 }
424 }
423
425
424− DirectionalDragArea {
426+ EdgeDragArea {
425 id: rightEdgeDraggingArea
427 id: rightEdgeDraggingArea
426
428
427 enabled: {
429 enabled: {
@@ -439,10 +441,6 @@ Showable {
439 anchors.right: parent.right
441 anchors.right: parent.right
440
442
441 direction: Direction.Leftwards
443 direction: Direction.Leftwards
442− maxDeviation: units.gu(1)
443− wideningAngle: 20
444− distanceThreshold: units.gu(3)
445− minSpeed: units.gu(5)
446
444
447 onDistanceChanged: {
445 onDistanceChanged: {
448 if (status !== DirectionalDragArea.Recognized)
446 if (status !== DirectionalDragArea.Recognized)
@@ -478,7 +476,7 @@ Showable {
478 }
476 }
479
477
480 function onUndecided() {
478 function onUndecided() {
481− dragVelocityCalculator.reset()
479+ dragEvaluator.reset();
482
480
483 var nextApplication = null;
481 var nextApplication = null;
484 if (stage.applications.count > 1) {
482 if (stage.applications.count > 1) {
@@ -491,7 +489,7 @@ Showable {
491 }
489 }
492
490
493 function onGestureEnded() {
491 function onGestureEnded() {
494− if (stage.applications.count > 1 && dragVelocityCalculator.calculate() < 0) {
492+ if (stage.applications.count > 1 && dragEvaluator.shouldAutoComplete()) {
495 switchToApplicationAnimationController.completeToEndWithSignal();
493 switchToApplicationAnimationController.completeToEndWithSignal();
496 } else {
494 } else {
497 switchToApplicationAnimationController.completeToBeginningWithSignal();
495 switchToApplicationAnimationController.completeToBeginningWithSignal();
Components/Tile.qml+1−1
@@ -51,7 +51,7 @@ AbstractButton {
51
51
52 anchors.fill: icon
52 anchors.fill: icon
53 radius: "medium"
53 radius: "medium"
54− borderSource: ItemStyle.style.borderPressed
54+ borderSource: "radius_pressed.sci"
55 opacity: root.pressed ? 1.0 : 0.0
55 opacity: root.pressed ? 1.0 : 0.0
56 Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.OutQuint } }
56 Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.OutQuint } }
57 }
57 }
Components/UbuntuShapeForItem.qml+12−56
@@ -15,7 +15,7 @@
15 */
15 */
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18−import Ubuntu.Components 0.1 as Theming
18+import Ubuntu.Components 0.1
19
19
20/* FIXME: This component is duplicating the UbuntuShape from the SDK, but shapes more
20/* FIXME: This component is duplicating the UbuntuShape from the SDK, but shapes more
21 * general (Item-based) components. This ability should be incorporated into the SDK's
21 * general (Item-based) components. This ability should be incorporated into the SDK's
@@ -24,66 +24,22 @@ import Ubuntu.Components 0.1 as Theming
24 */
24 */
25
25
26Item {
26Item {
27− id: shape
27+ id: root
28
28
29− Theming.ItemStyle.class: "UbuntuShape-radius-" + radius
29+ property alias radius: shape.radius
30+ property alias image: source.sourceItem
30
31
31− property string radius: "small"
32+ ShaderEffectSource {
32− property url maskSource: Theming.ComponentUtils.style(shape, "maskSource", "")
33− property url borderSource: Theming.ComponentUtils.style(shape, "borderIdle", "")
34− property Item image
35−
36− implicitWidth: units.gu(8)
37− implicitHeight: units.gu(8)
38−
39− onWidthChanged: __updateImageDimensions()
40− onHeightChanged: __updateImageDimensions()
41− onImageChanged: __updateImageDimensions()
42−
43− function __updateImageDimensions() {
44− if (!image) return;
45− image.width = shape.width;
46− image.height = shape.height;
47− image.visible = false;
48− }
49−
50− ShaderEffect {
51− anchors.fill: parent
52− visible: shape.image
53−
54− property ShaderEffectSource mask: ShaderEffectSource {
55− sourceItem: BorderImage {
56− width: shape.width
57− height: shape.height
58− source: shape.maskSource
33+ id: source
59− visible: false
34+ width: 1
60− }
35+ height: 1
61− }
36+ hideSource: true
62−
63− property ShaderEffectSource image: ShaderEffectSource {
64− sourceItem: shape.image
65− }
66−
67− fragmentShader:
68− "
69− varying highp vec2 qt_TexCoord0;
70− uniform lowp float qt_Opacity;
71− uniform sampler2D mask;
72− uniform sampler2D image;
73−
74− void main(void)
75− {
76− lowp vec4 maskColor = texture2D(mask, qt_TexCoord0.st);
77− lowp vec4 imageColor = texture2D(image, qt_TexCoord0.st);
78− gl_FragColor = imageColor * maskColor.a * qt_Opacity;
79− }
80− "
81 }
37 }
82
38
83− BorderImage {
39+ Shape {
84− id: border
40+ id: shape
41+ image: source
85
42
86 anchors.fill: parent
43 anchors.fill: parent
87− source: shape.borderSource
88 }
44 }
89}
45}
Components/WrongPasswordAnimation.qml+3−3
@@ -26,14 +26,14 @@ SequentialAnimation {
26 property: "anchors.horizontalCenterOffset"
26 property: "anchors.horizontalCenterOffset"
27 duration: 50
27 duration: 50
28 easing.type: Easing.InQuad
28 easing.type: Easing.InQuad
29− to: units.gu(2)
29+ to: units.gu(1)
30 }
30 }
31 NumberAnimation {
31 NumberAnimation {
32 target: root.target
32 target: root.target
33 property: "anchors.horizontalCenterOffset"
33 property: "anchors.horizontalCenterOffset"
34 duration: 100
34 duration: 100
35 easing.type: Easing.InOutQuad
35 easing.type: Easing.InOutQuad
36− to: -units.gu(2)
36+ to: -units.gu(1)
37 }
37 }
38 NumberAnimation {
38 NumberAnimation {
39 target: root.target
39 target: root.target
@@ -41,6 +41,6 @@ SequentialAnimation {
41 properties: "anchors.horizontalCenterOffset"
41 properties: "anchors.horizontalCenterOffset"
42 to: 0
42 to: 0
43 duration: 400
43 duration: 400
44− easing.overshoot: units.gu(2)
44+ easing.overshoot: units.gu(1)
45 }
45 }
46}
46}
Dash/Apps/RunningApplicationTile.qml+1−1
@@ -87,7 +87,7 @@ AbstractButton {
87
87
88 anchors.fill: shapedApplicationImage
88 anchors.fill: shapedApplicationImage
89 radius: "medium"
89 radius: "medium"
90− borderSource: ItemStyle.style.borderPressed
90+ borderSource: "radius_pressed.sci"
91 opacity: root.pressed ? 1.0 : 0.0
91 opacity: root.pressed ? 1.0 : 0.0
92 Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.OutQuint } }
92 Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.OutQuint } }
93 }
93 }
Dash/DashApps.qml+2−3
@@ -99,7 +99,7 @@ ScopeView {
99 When using Loader to load external QML file in the list deelgate, the ListView has
99 When using Loader to load external QML file in the list deelgate, the ListView has
100 a bug where it can position the delegate content to overlap the section header
100 a bug where it can position the delegate content to overlap the section header
101 of the ListView - a workaround is to use sourceComponent of Loader instead */
101 of the ListView - a workaround is to use sourceComponent of Loader instead */
102− Component { id: runningApplicationsGrid; RunningApplicationsGrid {} }
102+ Component { id: runningApplicationsGrid; RunningApplicationsGrid { clip: true } }
103 Component {
103 Component {
104 id: applicationsFilterGrid;
104 id: applicationsFilterGrid;
105 ApplicationsFilterGrid {
105 ApplicationsFilterGrid {
@@ -112,7 +112,7 @@ ScopeView {
112 "ApplicationsFilterGrid": applicationsFilterGrid,
112 "ApplicationsFilterGrid": applicationsFilterGrid,
113 }
113 }
114
114
115− ListViewWithPageHeader {
115+ ScopeListView {
116 id: categoryView
116 id: categoryView
117 anchors.fill: parent
117 anchors.fill: parent
118 model: SortFilterProxyModel {
118 model: SortFilterProxyModel {
@@ -150,7 +150,6 @@ ScopeView {
150 item.model = categoryModels[modelName]
150 item.model = categoryModels[modelName]
151 }
151 }
152 }
152 }
153− asynchronous: true
154 }
153 }
155
154
156 ListView.onRemove: SequentialAnimation {
155 ListView.onRemove: SequentialAnimation {
Dash/DashHome.qml+1−2
@@ -130,7 +130,7 @@ ScopeView {
130 "VideosGrid": videosGrid,
130 "VideosGrid": videosGrid,
131 }
131 }
132
132
133− ListViewWithPageHeader {
133+ ScopeListView {
134 id: listView
134 id: listView
135 anchors.fill: parent
135 anchors.fill: parent
136 model: categoryListModel
136 model: categoryListModel
@@ -161,7 +161,6 @@ ScopeView {
161 item.clicked.connect(playVideo);
161 item.clicked.connect(playVideo);
162 }
162 }
163 }
163 }
164− asynchronous: true
165 }
164 }
166 }
165 }
167
166
Dash/DashMusic.qml+1−2
@@ -64,7 +64,7 @@ ScopeView {
64 }
64 }
65 }
65 }
66
66
67− ListViewWithPageHeader {
67+ ScopeListView {
68 id: categoryView
68 id: categoryView
69 anchors.fill: parent
69 anchors.fill: parent
70 model: scopeView.categories
70 model: scopeView.categories
@@ -84,7 +84,6 @@ ScopeView {
84 onLoaded: {
84 onLoaded: {
85 item.model = results
85 item.model = results
86 }
86 }
87− asynchronous: true
88 }
87 }
89 }
88 }
90
89
Dash/DashVideos.qml+2−3
@@ -97,11 +97,11 @@ ScopeView {
97 }
97 }
98 }
98 }
99
99
100− ListViewWithPageHeader {
100+ ScopeListView {
101 id: categoryView
101 id: categoryView
102 anchors.fill: parent
102 anchors.fill: parent
103 model: scopeView.categories
103 model: scopeView.categories
104− clipListView: !previewLoader.onScreen
104+ forceNoClip: previewLoader.onScreen
105
105
106 onAtYEndChanged: if (atYEnd) endReached()
106 onAtYEndChanged: if (atYEnd) endReached()
107 onMovingChanged: if (moving && atYEnd) endReached()
107 onMovingChanged: if (moving && atYEnd) endReached()
@@ -119,7 +119,6 @@ ScopeView {
119 onLoaded: {
119 onLoaded: {
120 item.model = results
120 item.model = results
121 }
121 }
122− asynchronous: true
123
122
124 Connections {
123 Connections {
125 target: loader.item
124 target: loader.item
Dash/GenericScopeView.qml+1−1
@@ -43,7 +43,7 @@ ScopeView {
43 }
43 }
44 }
44 }
45
45
46− ListViewWithPageHeader {
46+ ScopeListView {
47 id: categoryView
47 id: categoryView
48 anchors.fill: parent
48 anchors.fill: parent
49 model: scopeView.categories
49 model: scopeView.categories
Dash/Music/AlbumTile.qml+1−1
@@ -45,7 +45,7 @@ AbstractButton {
45
45
46 anchors.fill: icon
46 anchors.fill: icon
47 radius: "medium"
47 radius: "medium"
48− borderSource: ItemStyle.style.borderPressed
48+ borderSource: "radius_pressed.sci"
49 opacity: root.pressed ? 1.0 : 0.0
49 opacity: root.pressed ? 1.0 : 0.0
50 Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.OutQuint } }
50 Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.OutQuint } }
51 }
51 }
Dash/ScopeListView.qmlnew file+23
@@ -0,0 +1,23 @@
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 ListViewWithPageHeader 0.1
19+
20+ListViewWithPageHeader {
21+ maximumFlickVelocity: height * 10
22+ flickDeceleration: height * 2
23+}
Greeter/Greeter.qml+28−2
@@ -16,14 +16,23 @@
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19+import Ubuntu.Gestures 0.1
19import LightDM 0.1 as LightDM
20import LightDM 0.1 as LightDM
20import "../Components"
21import "../Components"
22+import "../Components/Math.js" as MathLocal
21
23
22Showable {
24Showable {
23 id: greeter
25 id: greeter
24 enabled: shown
26 enabled: shown
25 created: greeterContentLoader.status == Loader.Ready && greeterContentLoader.item.ready
27 created: greeterContentLoader.status == Loader.Ready && greeterContentLoader.item.ready
26
28
29+ // 1 when fully shown and 0 when fully hidden
30+ property real showProgress: MathLocal.clamp((width + x) / width, 0, 1)
31+
32+ showAnimation: StandardAnimation { property: "x"; to: 0 }
33+ hideAnimation: StandardAnimation { property: "x"; to: -width }
34+
35+ property alias dragHandleWidth: dragHandle.width
27 property alias model: greeterContentLoader.model
36 property alias model: greeterContentLoader.model
28 property bool locked: shown && multiUser && !greeterContentLoader.promptless
37 property bool locked: shown && multiUser && !greeterContentLoader.promptless
29
38
@@ -39,7 +48,7 @@ Showable {
39 signal unlocked(int uid)
48 signal unlocked(int uid)
40
49
41 onRightTeaserPressedChanged: {
50 onRightTeaserPressedChanged: {
42− if (rightTeaserPressed) {
51+ if (rightTeaserPressed && !locked) {
43 teasingTimer.start();
52 teasingTimer.start();
44 }
53 }
45 }
54 }
@@ -72,7 +81,7 @@ Showable {
72 states: [
81 states: [
73 State {
82 State {
74 name: "teasing"
83 name: "teasing"
75− when: greeter.rightTeaserPressed || teasingTimer.running
84+ when: teasingTimer.running
76 PropertyChanges {
85 PropertyChanges {
77 target: greeter
86 target: greeter
78 x: -units.gu(2)
87 x: -units.gu(2)
@@ -91,4 +100,21 @@ Showable {
91 }
100 }
92 }
101 }
93 ]
102 ]
103+
104+ DragHandle {
105+ id: dragHandle
106+
107+ anchors.top: parent.top
108+ anchors.bottom: parent.bottom
109+ anchors.right: parent.right
110+
111+ // no need for requiring a directional drag since we are covering the screen
112+ // anyway (i.e., no change user could be trying to interact with some other
113+ // UI element)
114+ distanceThreshold: 0
115+
116+ enabled: !greeter.locked
117+
118+ direction: Direction.Leftwards
119+ }
94}
120}
Greeter/GreeterContent.qml+3−1
@@ -80,7 +80,9 @@ MouseArea {
80 source: greeter.narrowMode ? "" : "LoginList.qml"
80 source: greeter.narrowMode ? "" : "LoginList.qml"
81
81
82 onLoaded: {
82 onLoaded: {
83− item.currentIndex = greeterContentLoader.currentIndex
83+ item.currentIndex = greeterContentLoader.currentIndex;
84+ selected(item.currentIndex);
85+ item.resetAuthentication();
84 }
86 }
85
87
86 Binding {
88 Binding {
Greeter/LoginList.qml−8
@@ -66,14 +66,6 @@ Item {
66
66
67 readonly property bool movingInternally: moveTimer.running || userList.moving
67 readonly property bool movingInternally: moveTimer.running || userList.moving
68
68
69− onCountChanged: {
70− // Start authentication when we start up
71− if (!LightDM.Greeter.authenticationUser && userList.currentItem) {
72− root.selected(userList.currentIndex);
73− root.resetAuthentication();
74− }
75− }
76−
77 onCurrentIndexChanged: {
69 onCurrentIndexChanged: {
78 if (LightDM.Greeter.authenticationUser != userList.model.data(currentIndex, LightDM.UserRoles.NameRole)) {
70 if (LightDM.Greeter.authenticationUser != userList.model.data(currentIndex, LightDM.UserRoles.NameRole)) {
79 root.resetAuthentication();
71 root.resetAuthentication();
Hud/SearchBar.qml−7
@@ -55,13 +55,6 @@ Item {
55 }
55 }
56 }
56 }
57
57
58− // Don't let the style play with our opacity
59− Binding {
60− target: searchBar.ItemStyle.style
61− property: "opacity"
62− value: 1
63− }
64−
65 Item {
58 Item {
66 id: primary
59 id: primary
67 height: searchBar.height
60 height: searchBar.height
Hud/ToolBarIcon.qml+1−1
@@ -18,7 +18,7 @@ import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19
19
20Button {
20Button {
21− ItemStyle.class: "transparent-button"
21+ color: "transparent"
22
22
23 property alias source: image.source
23 property alias source: image.source
24
24
Launcher/Launcher.qml+9−17
@@ -25,7 +25,6 @@ Item {
25
25
26 property bool available: true // can be used to disable all interactions
26 property bool available: true // can be used to disable all interactions
27
27
28− property bool teasing: false
29 property int panelWidth: units.gu(8.5)
28 property int panelWidth: units.gu(8.5)
30 property int dragAreaWidth: units.gu(1)
29 property int dragAreaWidth: units.gu(1)
31 property real progress: dragArea.dragging && dragArea.touchX > panel.width ? dragArea.touchX : 0
30 property real progress: dragArea.dragging && dragArea.touchX > panel.width ? dragArea.touchX : 0
@@ -50,7 +49,7 @@ Item {
50 }
49 }
51
50
52 function hide() {
51 function hide() {
53− state = ""
52+ switchToNextState("")
54 }
53 }
55
54
56 function switchToNextState(state) {
55 function switchToNextState(state) {
@@ -58,8 +57,8 @@ Item {
58 animateTimer.start();
57 animateTimer.start();
59 }
58 }
60
59
61− onTeasingChanged: {
60+ function tease() {
62− if (teasing) {
61+ if (available) {
63 teaseTimer.start();
62 teaseTimer.start();
64 }
63 }
65 }
64 }
@@ -181,18 +180,11 @@ Item {
181 }
180 }
182 }
181 }
183
182
184− DirectionalDragArea {
183+ EdgeDragArea {
185 id: dragArea
184 id: dragArea
186
185
187 direction: Direction.Rightwards
186 direction: Direction.Rightwards
188
187
189− // values to be tweaked and later removed from here and set in stone as defaults
190− // once we are confident it's all good.
191− maxDeviation: units.gu(1)
192− wideningAngle: 30
193− distanceThreshold: units.gu(3)
194− minSpeed: units.gu(5)
195−
196 enabled: root.available && root.state !== "visible"
188 enabled: root.available && root.state !== "visible"
197 width: root.dragAreaWidth
189 width: root.dragAreaWidth
198 height: root.height
190 height: root.height
@@ -215,11 +207,11 @@ Item {
215
207
216 onDraggingChanged: {
208 onDraggingChanged: {
217 if (!dragging) {
209 if (!dragging) {
218− if (distance > root.width / 2) {
210+ if (distance > panel.width / 2) {
219− root.dash()
220− root.switchToNextState("")
221− } else if (distance > panel.width/2) {
222 root.switchToNextState("visible")
211 root.switchToNextState("visible")
212+ if (distance > panel.width * 2) {
213+ root.dash()
214+ }
223 } else {
215 } else {
224 root.switchToNextState("")
216 root.switchToNextState("")
225 }
217 }
@@ -244,7 +236,7 @@ Item {
244 },
236 },
245 State {
237 State {
246 name: "teasing"
238 name: "teasing"
247− when: root.teasing || teaseTimer.running
239+ when: teaseTimer.running
248 PropertyChanges {
240 PropertyChanges {
249 target: panel
241 target: panel
250 x: -root.panelWidth + units.gu(2)
242 x: -root.panelWidth + units.gu(2)
Launcher/LauncherDelegate.qml+202−39
@@ -25,6 +25,8 @@ Item {
25 property real angle: 0
25 property real angle: 0
26 property bool highlighted: false
26 property bool highlighted: false
27 property real offset: 0
27 property real offset: 0
28+ property alias brightness: transformEffect.brightness
29+ property real itemOpacity: 1
28
30
29 property real maxAngle: 0
31 property real maxAngle: 0
30 property bool inverted: false
32 property bool inverted: false
@@ -32,74 +34,237 @@ Item {
32 readonly property int effectiveHeight: Math.cos(angle * Math.PI / 180) * height
34 readonly property int effectiveHeight: Math.cos(angle * Math.PI / 180) * height
33 readonly property real foldedHeight: Math.cos(maxAngle * Math.PI / 180) * height
35 readonly property real foldedHeight: Math.cos(maxAngle * Math.PI / 180) * height
34
36
35− property int itemsBeforeThis: 0
36− property int itemsAfterThis: 0
37−
38 property bool dragging:false
37 property bool dragging:false
39
38
40 signal clicked()
39 signal clicked()
41 signal longtap()
40 signal longtap()
42 signal released()
41 signal released()
43
42
44− UbuntuShape {
43+ Item {
45 id: iconItem
44 id: iconItem
46− color: Qt.rgba(0, 0, 1, 0.5)
47 width: parent.width
45 width: parent.width
48 height: parent.height
46 height: parent.height
49 anchors.centerIn: parent
47 anchors.centerIn: parent
50− anchors.verticalCenterOffset: root.offset + (height - root.effectiveHeight)/2 * (angle < 0 ? -1 : 1)
51− rotation: root.inverted ? 180 : 0
52− radius: "medium"
53−
54− transform: Rotation {
55− axis { x: 1; y: 0; z: 0 }
56− origin { x: iconItem.width / 2; y: iconItem.height / 2; z: 0 }
57− angle: root.angle
58− }
59−
60− image: Image {
61− source: "../graphics/applicationIcons/" + root.iconName + ".png"
62− }
63
48
64− MouseArea {
49+ UbuntuShape {
65− id: mouseArea
50+ id: iconShape
66 anchors.fill: parent
51 anchors.fill: parent
67− onClicked: root.clicked()
52+ anchors.margins: units.gu(0.5)
68− onCanceled: root.released()
53+ radius: "medium"
69− preventStealing: false
70
54
71− onPressAndHold: {
55+ image: Image {
72− root.state = "moving"
56+ id: iconImage
57+ sourceSize.width: iconShape.width
58+ sourceSize.height: iconShape.height
59+ source: "../graphics/applicationIcons/" + root.iconName + ".png"
73 }
60 }
61+
62+ MouseArea {
63+ id: mouseArea
64+ anchors.fill: parent
65+ onClicked: root.clicked()
66+ onCanceled: root.released()
67+ preventStealing: false
68+ enabled: root.angle < 5
69+
70+ onPressAndHold: {
71+ root.state = "moving"
72+ }
74− onReleased: {
73+ onReleased: {
75− root.state = "docked"
74+ root.state = "docked"
75+ }
76 }
76 }
77 }
77 }
78−
79 BorderImage {
78 BorderImage {
80 id: overlayHighlight
79 id: overlayHighlight
81 anchors.centerIn: iconItem
80 anchors.centerIn: iconItem
82 rotation: inverted ? 180 : 0
81 rotation: inverted ? 180 : 0
83− source: root.highlighted || mouseArea.pressed ? "graphics/selected.sci" : "graphics/non-selected.sci"
82+ source: isSelected ? "graphics/selected.sci" : "graphics/non-selected.sci"
84− width: iconItem.width + units.gu(1.5)
83+ width: root.width + units.gu(0.5)
85 height: width
84 height: width
85+ property bool isSelected: root.highlighted || mouseArea.pressed
86+ onIsSelectedChanged: shaderEffectSource.scheduleUpdate();
86 }
87 }
87 }
88 }
88
89
90+ ShaderEffect {
91+ id: transformEffect
92+ anchors.centerIn: parent
93+ anchors.verticalCenterOffset: root.offset
94+ width: parent.width
95+ height: parent.height
96+ property real itemOpacity: root.itemOpacity
97+ property real brightness: 0
98+ property real angle: root.angle
99+ rotation: root.inverted ? 180 : 0
100+
101+
102+ property variant source: ShaderEffectSource {
103+ id: shaderEffectSource
104+ sourceItem: iconItem
105+ hideSource: true
106+ live: false
107+ }
108+
109+ transform: [
110+ // Rotating 3 times at top/bottom because that increases the perspective.
111+ // This is a hack, but as QML does not support real 3D coordinates
112+ // getting a higher perspective can only be done by a hack. This is the most
113+ // readable/understandable one I could come up with.
114+ Rotation {
115+ axis { x: 1; y: 0; z: 0 }
116+ origin { x: iconItem.width / 2; y: angle > 0 ? 0 : iconItem.height; z: 0 }
117+ angle: root.angle * 0.7
118+ },
119+ Rotation {
120+ axis { x: 1; y: 0; z: 0 }
121+ origin { x: iconItem.width / 2; y: angle > 0 ? 0 : iconItem.height; z: 0 }
122+ angle: root.angle * 0.7
123+ },
124+ Rotation {
125+ axis { x: 1; y: 0; z: 0 }
126+ origin { x: iconItem.width / 2; y: angle > 0 ? 0 : iconItem.height; z: 0 }
127+ angle: root.angle * 0.7
128+ },
129+ // Because rotating it 3 times moves it more to the front/back, i.e. it gets
130+ // bigger/smaller and we need a scale to compensate that again.
131+ Scale {
132+ xScale: 1 - (Math.abs(angle) / 500)
133+ yScale: 1 - (Math.abs(angle) / 500)
134+ origin { x: iconItem.width / 2; y: iconItem.height / 2}
135+ }
136+ ]
137+
138+ // Using a fragment shader instead of QML's opacity and BrightnessContrast
139+ // to be able to do both in one step which gives quite some better performance
140+ fragmentShader: "
141+ varying highp vec2 qt_TexCoord0;
142+ uniform sampler2D source;
143+ uniform lowp float brightness;
144+ uniform lowp float itemOpacity;
145+ void main(void)
146+ {
147+ highp vec4 sourceColor = texture2D(source, qt_TexCoord0);
148+ sourceColor.rgb = mix(sourceColor.rgb, vec3(step(0.0, brightness)), abs(brightness));
149+ sourceColor *= itemOpacity;
150+ gl_FragColor = sourceColor;
151+ }"
152+ }
153+
154+ QtObject {
155+ id: priv
156+
157+ property ListView listView: root.ListView.view
158+ property real totalUnfoldedHeight: listView.itemSize + listView.spacing
159+ property real totalEffectiveHeight: effectiveHeight + listView.spacing
160+ property real effectiveContentY: listView.contentY - listView.originY
161+ property real effectiveY: y - listView.originY
162+ property real distanceFromTopEdge: -(effectiveContentY + listView.topMargin - index*totalUnfoldedHeight)
163+ property real distanceFromBottomEdge: listView.height - listView.bottomMargin - (effectiveY+height) + effectiveContentY
164+
165+ property real distanceFromEdge: Math.abs(distanceFromBottomEdge) < Math.abs(distanceFromTopEdge) ? distanceFromBottomEdge : distanceFromTopEdge
166+ property real orientationFlag: Math.abs(distanceFromBottomEdge) < Math.abs(distanceFromTopEdge) ? -1 : 1
167+
168+ property real overlapWithFoldingArea: listView.foldingAreaHeight - distanceFromEdge
169+ }
170+
89 states: [
171 states: [
90 State {
172 State {
91 name: "docked"
173 name: "docked"
92 PropertyChanges {
174 PropertyChanges {
93 target: root
175 target: root
94− offset: if (launcherFlickable.contentY > itemsBeforeThis * (foldedHeight + launcherColumn.spacing*2)) {
176+
95− return launcherFlickable.contentY - (index * (foldedHeight + launcherColumn.spacing*2));
177+ // This is the offset that keeps the items inside the panel
96− } else if (y + height - launcherFlickable.contentY > launcherFlickable.height - (itemsAfterThis*(foldedHeight - launcherColumn.spacing))) {
178+ offset: {
97− return launcherFlickable.height - (y+height) + launcherFlickable.contentY - (itemsAfterThis*(foldedHeight - launcherColumn.spacing));
179+ // First/last items are special
98− } else {
180+ if (index == 0 || index == priv.listView.count-1) {
99− return 0;
181+ // Just keep them bound to the edges in case they're outside of the visible area
182+ if (priv.distanceFromEdge < 0) {
183+ return (-priv.distanceFromEdge - (height - effectiveHeight)) * priv.orientationFlag;
184+ }
185+ return 0;
186+ }
187+
188+ // Are we already completely outside the flickable? Stop the icon here.
189+ if (priv.distanceFromEdge < -priv.totalUnfoldedHeight) {
190+ return (-priv.distanceFromEdge - (root.height - effectiveHeight)) * priv.orientationFlag;
191+ }
192+
193+ // We're touching the edge, move slower than the actual flicking speed.
194+ if (priv.distanceFromEdge < 0) {
195+ return (Math.abs(priv.distanceFromEdge) * priv.totalEffectiveHeight / priv.totalUnfoldedHeight) * priv.orientationFlag
196+ }
197+ return 0;
198+ }
199+
200+ // The angle used for rotating
201+ angle: {
202+ // First/last items are special
203+ if (index == 0 || index == priv.listView.count-1) {
204+ if (priv.distanceFromEdge < 0) {
205+ // proportion equation: distanceFromTopEdge : angle = totalUnfoldedHeight/2 : maxAngle
206+ return Math.max(-maxAngle, priv.distanceFromEdge * maxAngle / (priv.listView.foldingAreaHeight)) * priv.orientationFlag
100 }
207 }
101− angle: -Math.min(Math.max(offset * maxAngle / foldedHeight, -maxAngle), maxAngle)
208+ return 0; // Don't fold first/last item as long as inside the view
209+ }
102
210
211+ // Are we in the already completely outside the flickable? Fold for the last 5 degrees
212+ if (priv.distanceFromEdge < 0) {
213+ // proportion equation: -distanceFromTopEdge : angle = totalUnfoldedHeight : 5
214+ return Math.max(-maxAngle, (priv.distanceFromEdge * 5 / priv.listView.foldingAreaHeight) - (maxAngle-5)) * priv.orientationFlag
215+ }
216+
217+ // We are overlapping with the folding area, fold the icon to maxAngle - 5 degrees
218+ if (priv.overlapWithFoldingArea > 0) {
219+ // proportion equation: overlap: totalHeight = angle : (maxAngle - 5)
220+ return -priv.overlapWithFoldingArea * (maxAngle -5) / priv.listView.foldingAreaHeight * priv.orientationFlag;
221+ }
222+ return 0;
223+ }
224+
225+ itemOpacity: {
226+ // First/last items are special
227+ if (index == 0 || index == priv.listView.count-1) {
228+ if (priv.distanceFromEdge < 0) {
229+ // Fade from 1 to 0 in the distance of 3 * foldingAreaHeight (which is when the next item reaches the edge)
230+ return 1.0 - (-priv.distanceFromEdge / (priv.listView.foldingAreaHeight * 3))
231+ }
232+ return 1; // Don't make first/last item transparent as long as inside the view
233+ }
234+
235+ // Are we already completely outside the flickable? Fade from 0.75 to 0 in 2 items height
236+ if (priv.distanceFromEdge < 0) {
237+ // proportion equation: -distanceFromEdge : 1-opacity = totalUnfoldedHeight : 0.75
238+ return 0.75 - (-priv.distanceFromEdge * 0.75 / (priv.totalUnfoldedHeight*2))
239+ }
240+
241+ // We are overlapping with the folding area, fade out to 0.75
242+ if (priv.overlapWithFoldingArea > 0) {
243+ // proportion equation: overlap : totalHeight = 1-opacity : 0.25
244+ return 1 - (priv.overlapWithFoldingArea * 0.25 / priv.listView.foldingAreaHeight)
245+ }
246+ return 1;
247+ }
248+
249+ brightness: {
250+ // First/last items are special
251+ if (index == 0 || index == priv.listView.count-1) {
252+ if (priv.distanceFromEdge < 0) {
253+ return -(-priv.distanceFromEdge / (priv.listView.foldingAreaHeight * 3))
254+ }
255+ return 0;
256+ }
257+ // Are we already completely outside the flickable? Fade from 0.7 to 0 in 2 items height
258+ if (priv.distanceFromEdge < 0) {
259+ return -0.3 - (-priv.distanceFromEdge * 0.1 / (priv.totalUnfoldedHeight*2))
260+ }
261+
262+ // We are overlapping with the folding area, fade out to 0.7
263+ if (priv.overlapWithFoldingArea > 0) {
264+ return - (priv.overlapWithFoldingArea * 0.3 / priv.listView.foldingAreaHeight)
265+ }
266+ return 0;
267+ }
103 }
268 }
104 },
269 },
105
270
@@ -121,7 +286,5 @@ Item {
121 drag.target: root
286 drag.target: root
122 }
287 }
123 }
288 }
124−
125 ]
289 ]
126−
127}
290}
Launcher/LauncherPanel.qml+106−52
@@ -17,6 +17,7 @@
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19import Unity 0.1
19import Unity 0.1
20+import "../Components/ListItems"
20
21
21Item {
22Item {
22 id: root
23 id: root
@@ -26,7 +27,7 @@ Item {
26 property var model
27 property var model
27 property bool inverted: true
28 property bool inverted: true
28 property bool dragging: false
29 property bool dragging: false
29− property bool moving: launcherFlickable.moving
30+ property bool moving: launcherListView.moving || launcherListView.flicking
30 property int dragPosition: 0
31 property int dragPosition: 0
31 property int highlightIndex: -1
32 property int highlightIndex: -1
32
33
@@ -34,23 +35,23 @@ Item {
34 signal dashItemSelected(int index)
35 signal dashItemSelected(int index)
35
36
36 onDragPositionChanged: {
37 onDragPositionChanged: {
37− var effectiveDragPosition = root.inverted ? launcherFlickable.height - dragPosition : dragPosition - mainColumn.anchors.margins
38+ var effectiveDragPosition = root.inverted ? launcherListView.height - dragPosition : dragPosition - mainColumn.anchors.margins
38
39
39− var hiddenContentHeight = launcherFlickable.contentHeight - launcherFlickable.height
40+ var hiddenContentHeight = launcherListView.contentHeight - launcherListView.height
40 // Shortening scrollable height because the first/last item needs to be fully expanded before reaching the top/bottom
41 // Shortening scrollable height because the first/last item needs to be fully expanded before reaching the top/bottom
41− var scrollableHeight = launcherFlickable.height - (launcherFlickable.itemSize + launcherColumn.spacing) *2
42+ var scrollableHeight = launcherListView.height - (launcherListView.itemSize + launcherColumn.spacing) *2
42 // As we shortened the scrollableHeight, lets move everything down by the itemSize
43 // As we shortened the scrollableHeight, lets move everything down by the itemSize
43− var shortenedEffectiveDragPosition = effectiveDragPosition - launcherFlickable.itemSize - launcherColumn.spacing
44+ var shortenedEffectiveDragPosition = effectiveDragPosition - launcherListView.itemSize - launcherColumn.spacing
44 var newContentY = shortenedEffectiveDragPosition * hiddenContentHeight / scrollableHeight
45 var newContentY = shortenedEffectiveDragPosition * hiddenContentHeight / scrollableHeight
45
46
46 // limit top/bottom to prevent overshooting
47 // limit top/bottom to prevent overshooting
47− launcherFlickable.contentY = Math.min(hiddenContentHeight, Math.max(0, newContentY));
48+ launcherListView.contentY = Math.min(hiddenContentHeight, Math.max(0, newContentY));
48
49
49 // Now calculate the current index:
50 // Now calculate the current index:
50 // > the current mouse position + the hidden/scolled content on top is the mouse position in the averall view
51 // > the current mouse position + the hidden/scolled content on top is the mouse position in the averall view
51 // > adjust that removing all the margins
52 // > adjust that removing all the margins
52 // > divide by itemSize to get index
53 // > divide by itemSize to get index
53− highlightIndex = (effectiveDragPosition + launcherFlickable.contentY - mainColumn.anchors.margins*3 - launcherColumn.spacing/2) / (launcherFlickable.itemSize + launcherColumn.spacing)
54+ highlightIndex = (effectiveDragPosition + launcherListView.contentY - mainColumn.anchors.margins*3 - launcherColumn.spacing/2) / (launcherListView.itemSize + launcherColumn.spacing)
54 }
55 }
55
56
56 BorderImage {
57 BorderImage {
@@ -61,58 +62,111 @@ Item {
61
62
62 Column {
63 Column {
63 id: mainColumn
64 id: mainColumn
65+ anchors {
64− anchors.fill: parent
66+ fill: parent
65− anchors.margins: units.gu(1)
67+ topMargin: units.gu(0.5)
68+ bottomMargin: units.gu(1)
69+ leftMargin: units.gu(0.5)
70+ rightMargin: units.gu(0.5)
71+ }
66− spacing: units.gu(1)
72+ spacing: units.gu(0.5)
67
73
68− LauncherDelegate {
74+ MouseArea {
69 id: dashItem
75 id: dashItem
70− objectName: "dashItem"
76+ width: parent.width
71− width: launcherFlickable.itemSize
77+ height: units.gu(6.5)
72− height: launcherFlickable.itemSize
73− anchors.horizontalCenter: parent.horizontalCenter
74− iconName: "dash"
75 onClicked: root.dashItemSelected(0)
78 onClicked: root.dashItemSelected(0)
79+ z: 1
80+ Image {
81+ objectName: "dashItem"
82+ width: units.gu(5.5)
83+ height: width
84+ anchors.centerIn: parent
85+ source: "graphics/home.png"
86+ }
76 }
87 }
77− Flickable {
88+ ThinDivider {
78− id: launcherFlickable
89+ anchors {
90+ left: parent.left
91+ right: parent.right
92+ margins: -mainColumn.anchors.leftMargin
93+ }
94+ rotation: root.rotation
95+ }
96+
97+ Item {
79 anchors.left: parent.left
98 anchors.left: parent.left
80 anchors.right: parent.right
99 anchors.right: parent.right
81− height: parent.height - dashItem.height - parent.spacing
100+ height: parent.height - dashItem.height - parent.spacing*2
82− contentHeight: launcherColumn.height
101+ ListView {
83−
102+ id: launcherListView
84− property int itemSize: width
103+ anchors.fill: parent
85−
104+ anchors.topMargin: -itemSize
86− Column {
105+ anchors.bottomMargin: -itemSize
87− id: launcherColumn
106+ topMargin: itemSize
88− width: parent.width
107+ bottomMargin: itemSize
89− spacing: units.gu(1)
108+ height: parent.height - dashItem.height - parent.spacing*2
90− anchors.horizontalCenter: parent.horizontalCenter
109+ model: root.model
91−
110+ cacheBuffer: itemSize * 3
92− Repeater {
111+ snapMode: ListView.SnapToItem
93− id: iconRepeater
112+ highlightRangeMode: ListView.ApplyRange
94− model: root.model
113+ preferredHighlightBegin: (height - itemSize) / 2
95−
114+ preferredHighlightEnd: (height + itemSize) / 2
115+
116+ // The height of the area where icons start getting folded
117+ property int foldingAreaHeight: itemSize * 0.75
118+ property int itemSize: width
119+
120+ Component.onCompleted: {
121+ // This is needed because snapping would partially fold
122+ // the first item on initialisation. This can only be
123+ // overridden by mouse interactions - which is what flick()
124+ // simulates. Setting contentY to 0 would not work because
125+ // of this.
126+ flick(0, units.gu(20))
127+ }
128+
96− LauncherDelegate {
129+ delegate: LauncherDelegate {
97− id: launcherDelegate
130+ id: launcherDelegate
98− objectName: "launcherDelegate" + index
131+ objectName: "launcherDelegate" + index
99− width: launcherFlickable.itemSize
132+ width: launcherListView.itemSize
100− height: launcherFlickable.itemSize
133+ height: launcherListView.itemSize
101− iconName: model.icon
134+ iconName: model.icon
102− inverted: root.inverted
135+ inverted: root.inverted
103− highlighted: root.dragging && index === root.highlightIndex
136+ highlighted: root.dragging && index === root.highlightIndex
104− z: -Math.abs(offset)
137+ z: -Math.abs(offset)
105− state: "docked"
138+ state: "docked"
106−
107− maxAngle: 60
139+ maxAngle: 60
108−
140+
109− itemsBeforeThis: index
110− itemsAfterThis: iconRepeater.count - (index+1)
111−
112− onClicked: {
141+ onClicked: {
113− root.applicationSelected(launcherModel.get(index).desktopFile);
142+ root.applicationSelected(launcherModel.get(index).desktopFile);
143+ }
144+ }
145+
146+ MouseArea {
147+ id: topFoldingArea
148+ anchors {
149+ left: parent.left
150+ right: parent.right
151+ top: parent.top
152+ topMargin: launcherListView.topMargin
114− }
153+ }
154+ height: launcherListView.itemSize
155+ enabled: launcherListView.contentY > -launcherListView.topMargin
156+ onClicked: launcherListView.flick(0, units.gu(40))
157+ }
158+
159+ MouseArea {
160+ id: bottomFoldingArea
161+ anchors {
162+ left: parent.left
163+ right: parent.right
164+ bottom: parent.bottom
165+ bottomMargin: launcherListView.bottomMargin
115 }
166 }
167+ height: launcherListView.itemSize
168+ enabled: launcherListView.contentHeight - launcherListView.height - launcherListView.contentY > -launcherListView.bottomMargin
169+ onClicked: launcherListView.flick(0, -units.gu(40))
116 }
170 }
117 }
171 }
118 }
172 }
Launcher/graphics/home@18.pngnew file

Binary file not shown.

Shell.qml+42−40
@@ -17,6 +17,7 @@
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Application 0.1
18import Ubuntu.Application 0.1
19import Ubuntu.Components 0.1
19import Ubuntu.Components 0.1
20+import Ubuntu.Gestures 0.1
20import LightDM 0.1 as LightDM
21import LightDM 0.1 as LightDM
21import "Dash"
22import "Dash"
22import "Greeter"
23import "Greeter"
@@ -167,7 +168,14 @@ FocusScope {
167
168
168 contentScale: 1.0 - 0.2 * disappearingAnimationProgress
169 contentScale: 1.0 - 0.2 * disappearingAnimationProgress
169 opacity: 1.0 - disappearingAnimationProgress
170 opacity: 1.0 - disappearingAnimationProgress
170− property real disappearingAnimationProgress: ((greeter.shown) ? greeterRevealer.animatedProgress : stagesRevealer.animatedProgress)
171+ property real disappearingAnimationProgress: {
172+ if (greeter.shown) {
173+ return greeter.showProgress;
174+ } else {
175+ return stagesOuterContainer.showProgress;
176+ }
177+ }
178+
171 // FIXME: only necessary because stagesRevealer.animatedProgress and
179 // FIXME: only necessary because stagesRevealer.animatedProgress and
172 // greeterRevealer.animatedProgress are not animated
180 // greeterRevealer.animatedProgress are not animated
173 Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
181 Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
@@ -176,26 +184,29 @@ FocusScope {
176
184
177
185
178 Item {
186 Item {
187+ id: stagesOuterContainer
179
188
180 width: parent.width
189 width: parent.width
181 height: parent.height
190 height: parent.height
182 x: launcher.progress
191 x: launcher.progress
183 Behavior on x {SmoothedAnimation{velocity: 600}}
192 Behavior on x {SmoothedAnimation{velocity: 600}}
184
193
194+ property real showProgress:
195+ MathLocal.clamp(1 - (x + stages.x) / shell.width, 0, 1)
185
196
186 Showable {
197 Showable {
187 id: stages
198 id: stages
188
199
189− property bool fullyShown: shown && stages[stagesRevealer.boundProperty] == stagesRevealer.openedValue
200+ x: width
190− && parent.x == 0
191
201
192− property bool fullyHidden: !shown && stages[stagesRevealer.boundProperty] == stagesRevealer.closedValue
202+ property bool fullyShown: shown && x == 0 && parent.x == 0
203+ property bool fullyHidden: !shown && x == width
193 available: !greeter.shown
204 available: !greeter.shown
194 hides: [launcher, panel.indicators]
205 hides: [launcher, panel.indicators]
195 shown: false
206 shown: false
196 opacity: 1.0
207 opacity: 1.0
197− showAnimation: StandardAnimation { property: "x"; duration: 350; to: stagesRevealer.openedValue; easing.type: Easing.OutCubic }
208+ showAnimation: StandardAnimation { property: "x"; duration: 350; to: 0; easing.type: Easing.OutCubic }
198− hideAnimation: StandardAnimation { property: "x"; duration: 350; to: stagesRevealer.closedValue; easing.type: Easing.OutCubic }
209+ hideAnimation: StandardAnimation { property: "x"; duration: 350; to: width; easing.type: Easing.OutCubic }
199
210
200 width: parent.width
211 width: parent.width
201 height: parent.height
212 height: parent.height
@@ -326,24 +337,19 @@ FocusScope {
326 height: sideStage.height
337 height: sideStage.height
327 orientation: Qt.Horizontal
338 orientation: Qt.Horizontal
328 }
339 }
329− }
330− }
331
340
341+ DragHandle {
342+ id: stagesRevealer
343+
344+ anchors.top: parent.top
345+ anchors.bottom: parent.bottom
346+ anchors.right: parent.left
332
347
333− Revealer {
348+ width: shell.edgeSize
334− id: stagesRevealer
349+ direction: Direction.Leftwards
335−
336− property real animatedProgress: MathLocal.clamp((-dragPosition - launcher.progress) / closedValue, 0, 1)
337− enabled: mainStage.applications.count > 0 || sideStage.applications.count > 0
350+ enabled: mainStage.applications.count > 0 || sideStage.applications.count > 0
338− direction: Qt.RightToLeft
351+ }
339− openedValue: 0
352+ }
340− hintDisplacement: units.gu(3)
341− handleSize: shell.edgeSize
342− closedValue: width
343− target: stages
344− width: stages.width
345− height: stages.height
346− orientation: Qt.Horizontal
347 }
353 }
348
354
349 Lockscreen {
355 Lockscreen {
@@ -392,12 +398,13 @@ FocusScope {
392 available: true
398 available: true
393 hides: [launcher, panel.indicators, hud]
399 hides: [launcher, panel.indicators, hud]
394 shown: true
400 shown: true
395− showAnimation: StandardAnimation { property: "x"; to: greeterRevealer.openedValue }
401+
396− hideAnimation: StandardAnimation { property: "x"; to: greeterRevealer.closedValue }
397 y: panel.panelHeight
402 y: panel.panelHeight
398 width: parent.width
403 width: parent.width
399 height: parent.height - panel.panelHeight
404 height: parent.height - panel.panelHeight
400
405
406+ dragHandleWidth: shell.edgeSize
407+
401 property var previousMainApp: null
408 property var previousMainApp: null
402 property var previousSideApp: null
409 property var previousSideApp: null
403
410
@@ -432,6 +439,12 @@ FocusScope {
432 var bgPath = greeter.model.data(uid, LightDM.UserRoles.BackgroundPathRole)
439 var bgPath = greeter.model.data(uid, LightDM.UserRoles.BackgroundPathRole)
433 shell.background = bgPath ? bgPath : default_background
440 shell.background = bgPath ? bgPath : default_background
434 }
441 }
442+
443+ onLeftTeaserPressedChanged: {
444+ if (leftTeaserPressed) {
445+ launcher.tease();
446+ }
447+ }
435 }
448 }
436
449
437 InputFilterArea {
450 InputFilterArea {
@@ -439,19 +452,6 @@ FocusScope {
439 blockInput: greeter.shown || lockscreen.shown
452 blockInput: greeter.shown || lockscreen.shown
440 }
453 }
441
454
442− Revealer {
443− id: greeterRevealer
444−
445− property real animatedProgress: MathLocal.clamp(-dragPosition / closedValue, 0, 1)
446− target: greeter
447− width: greeter.width
448− height: greeter.height
449− handleSize: shell.edgeSize
450− orientation: Qt.Horizontal
451− visible: greeter.shown
452− enabled: !greeter.locked
453− }
454−
455 Item {
455 Item {
456 id: overlay
456 id: overlay
457
457
@@ -538,7 +538,6 @@ FocusScope {
538 width: parent.width
538 width: parent.width
539 dragAreaWidth: shell.edgeSize
539 dragAreaWidth: shell.edgeSize
540 available: !greeter.locked
540 available: !greeter.locked
541− teasing: available && greeter.leftTeaserPressed
542 onDashItemSelected: {
541 onDashItemSelected: {
543 greeter.hide()
542 greeter.hide()
544 // Animate if moving between application and dash
543 // Animate if moving between application and dash
@@ -550,8 +549,11 @@ FocusScope {
550 stages.hide();
549 stages.hide();
551 }
550 }
552 onDash: {
551 onDash: {
552+ if (stages.shown) {
553− dash.setCurrentScope("applications.scope", true, false)
553+ dash.setCurrentScope("applications.scope", true, false)
554− stages.hide();
554+ stages.hide();
555+ launcher.hide();
556+ }
555 }
557 }
556 onLauncherApplicationSelected:{
558 onLauncherApplicationSelected:{
557 greeter.hide()
559 greeter.hide()
build+2
@@ -49,6 +49,8 @@ install_dependencies() {
49 indicators-client-plugin-* \
49 indicators-client-plugin-* \
50 ubuntu-mobile-icons \
50 ubuntu-mobile-icons \
51 unity-notifications-impl-1 \
51 unity-notifications-impl-1 \
52+ unity-scope-home \
53+ unity-lens-applications \
52 || exit 5
54 || exit 5
53}
55}
54
56
debian/changelog+24
@@ -1,3 +1,27 @@
1+unity8 (7.81.3) UNRELEASED; urgency=low
2+
3+ * Choose more appropriate values for edge-drag gestures (LP: #1194150)
4+
5+ -- Daniel d'Andrada <daniel.dandrada@canonical.com> Fri, 28 Jun 2013 16:28:24 -0300
6+
7+unity8 (7.81.2) saucy; urgency=low
8+
9+ * Translation updates.
10+
11+ [ Michał Sawicz ]
12+ * Fix icons in ApplicationsFilterGrid.qml.
13+ * Support flipped image in run_on_device.
14+
15+ [ Michael Zanetti ]
16+ * Don't clear lockscreen when it's fading out.
17+ * Reworked Launcher folding.
18+ * Tweak Launcher revealing.
19+
20+ [ Michal Hruby ]
21+ * Add content_type property to category models.
22+
23+ -- Michał Sawicz <michal.sawicz@canonical.com> Wed, 26 Jun 2013 18:10:39 +0200
24+
1unity8 (7.81.1) saucy; urgency=low
25unity8 (7.81.1) saucy; urgency=low
2
26
3 * Translation updates.
27 * Translation updates.
debian/control+2
@@ -11,6 +11,7 @@ Build-Depends: cmake,
11 libgles2-mesa-dev[armhf],
11 libgles2-mesa-dev[armhf],
12 libhud-client2-dev,
12 libhud-client2-dev,
13 libpulse-dev,
13 libpulse-dev,
14+ libqt5v8-5-private-dev,
14 libunity-core-6.0-dev (<< 7.80),
15 libunity-core-6.0-dev (<< 7.80),
15 libxcb1-dev,
16 libxcb1-dev,
16 pkg-config,
17 pkg-config,
@@ -20,6 +21,7 @@ Build-Depends: cmake,
20 qtbase5-private-dev,
21 qtbase5-private-dev,
21 qtdeclarative5-dev,
22 qtdeclarative5-dev,
22 qtdeclarative5-dev-tools,
23 qtdeclarative5-dev-tools,
24+ qtdeclarative5-private-dev,
23 qtdeclarative5-qtquick2-plugin,
25 qtdeclarative5-qtquick2-plugin,
24 qtdeclarative5-test-plugin,
26 qtdeclarative5-test-plugin,
25 qtdeclarative5-ubuntu-ui-toolkit-plugin,
27 qtdeclarative5-ubuntu-ui-toolkit-plugin,
debian/unity8.install+1
@@ -15,6 +15,7 @@
15/usr/share/unity8/graphics/*
15/usr/share/unity8/graphics/*
16/usr/share/unity8/plugins/HudClient/*
16/usr/share/unity8/plugins/HudClient/*
17/usr/share/unity8/plugins/LightDM/*
17/usr/share/unity8/plugins/LightDM/*
18+/usr/share/unity8/plugins/ListViewWithPageHeader/*
18/usr/share/unity8/plugins/Ubuntu/*
19/usr/share/unity8/plugins/Ubuntu/*
19/usr/share/unity8/plugins/Unity/*
20/usr/share/unity8/plugins/Unity/*
20/usr/share/unity8/plugins/Utils/*
21/usr/share/unity8/plugins/Utils/*
main.cpp+26−6
@@ -31,13 +31,33 @@
31#include "MouseTouchAdaptor.h"
31#include "MouseTouchAdaptor.h"
32
32
33namespace {
33namespace {
34+
35+void prependImportPaths(QQmlEngine *engine, const QStringList &paths)
36+{
37+ QStringList importPathList = engine->importPathList();
38+ for (int i = paths.count() -1; i >= 0; i--) {
39+ // don't duplicate
40+ const QString& path = paths[i];
41+ QStringList::iterator iter = qFind(importPathList.begin(), importPathList.end(), path);
42+ if (iter == importPathList.end())
43+ importPathList.prepend(path);
44+ }
45+ engine->setImportPathList(importPathList);
46+}
47+
34/* When you append and import path to the list of import paths it will be the *last*
48/* When you append and import path to the list of import paths it will be the *last*
35 place where Qt will search for QML modules.
49 place where Qt will search for QML modules.
36 The usual QQmlEngine::addImportPath() actually prepends the given path.*/
50 The usual QQmlEngine::addImportPath() actually prepends the given path.*/
37−void appendImportPath(QQmlEngine *engine, const QString &path)
51+void appendImportPaths(QQmlEngine *engine, const QStringList &paths)
38{
52{
39 QStringList importPathList = engine->importPathList();
53 QStringList importPathList = engine->importPathList();
54+ Q_FOREACH(const QString& path, paths) {
55+ // don't duplicate
56+ QStringList::iterator iter = qFind(importPathList.begin(), importPathList.end(), path);
57+ if (iter == importPathList.end())
40− importPathList.append(path);
58+ importPathList.append(path);
59+ }
60+ importPathList.append(paths);
41 engine->setImportPathList(importPathList);
61 engine->setImportPathList(importPathList);
42}
62}
43
63
@@ -88,7 +108,7 @@ int main(int argc, char** argv)
88 QQuickView* view = new QQuickView();
108 QQuickView* view = new QQuickView();
89 view->setResizeMode(QQuickView::SizeRootObjectToView);
109 view->setResizeMode(QQuickView::SizeRootObjectToView);
90 view->setTitle("Qml Phone Shell");
110 view->setTitle("Qml Phone Shell");
91− view->engine()->setBaseUrl(QUrl::fromLocalFile(shellAppDirectory()));
111+ view->engine()->setBaseUrl(QUrl::fromLocalFile(::shellAppDirectory()));
92 if (args.contains(QLatin1String("-frameless"))) {
112 if (args.contains(QLatin1String("-frameless"))) {
93 view->setFlags(Qt::FramelessWindowHint);
113 view->setFlags(Qt::FramelessWindowHint);
94 }
114 }
@@ -114,9 +134,9 @@ int main(int argc, char** argv)
114 QObject::connect(view->engine(), SIGNAL(quit()), qApp, SLOT(quit()));
134 QObject::connect(view->engine(), SIGNAL(quit()), qApp, SLOT(quit()));
115
135
116 QUrl source("Shell.qml");
136 QUrl source("Shell.qml");
117− view->engine()->addImportPath(shellAppDirectory());
137+ prependImportPaths(view->engine(), QStringList() << ::shellAppDirectory());
118− view->engine()->addImportPath(shellImportPath());
138+ prependImportPaths(view->engine(), ::shellImportPaths());
119− appendImportPath(view->engine(), fakePluginsImportPath());
139+ appendImportPaths(view->engine(), QStringList() << ::fakePluginsImportPath());
120 view->setSource(source);
140 view->setSource(source);
121 view->setColor("transparent");
141 view->setColor("transparent");
122
142
paths.h.in+10−3
@@ -17,6 +17,9 @@
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
18 */
19
19
20+#ifndef PATHS_H
21+#define PATHS_H
22+
20// Qt
23// Qt
21#include <QtCore/QCoreApplication>
24#include <QtCore/QCoreApplication>
22#include <QtCore/QDir>
25#include <QtCore/QDir>
@@ -43,12 +46,14 @@ inline QString shellAppDirectory() {
43 }
46 }
44}
47}
45
48
46−inline QString shellImportPath() {
49+inline QStringList shellImportPaths() {
50+ QStringList paths;
47 if (isRunningInstalled()) {
51 if (isRunningInstalled()) {
48− return QString("@CMAKE_INSTALL_PREFIX@/@SHELL_APP_DIR@/plugins");
52+ paths << QString("@CMAKE_INSTALL_PREFIX@/@SHELL_APP_DIR@/plugins");
49 } else {
53 } else {
50− return QString("@CMAKE_BINARY_DIR@/plugins/");
54+ paths << QString("@CMAKE_BINARY_DIR@/plugins");
51 }
55 }
56+ return paths;
52}
57}
53
58
54inline QString fakePluginsImportPath() {
59inline QString fakePluginsImportPath() {
@@ -62,3 +67,5 @@ inline QString fakePluginsImportPath() {
62inline QString sourceDirectory() {
67inline QString sourceDirectory() {
63 return QString("@CMAKE_SOURCE_DIR@/");
68 return QString("@CMAKE_SOURCE_DIR@/");
64}
69}
70+
71+#endif
plugins/CMakeLists.txt+1
@@ -3,3 +3,4 @@ add_subdirectory(Utils)
3add_subdirectory(Unity)
3add_subdirectory(Unity)
4add_subdirectory(HudClient)
4add_subdirectory(HudClient)
5add_subdirectory(LightDM)
5add_subdirectory(LightDM)
6+add_subdirectory(ListViewWithPageHeader)
plugins/ListViewWithPageHeader/CMakeLists.txtnew file+44
@@ -0,0 +1,44 @@
1+# There's no cmake var for v8 include path :-/
2+# so create one
3+LIST(GET Qt5Core_INCLUDE_DIRS 0 QtCoreDir0)
4+SET(Qt5V8_PRIVATE_INCLUDE_DIR ${QtCoreDir0}/../QtV8/${Qt5Core_VERSION_STRING}/QtV8)
5+
6+include_directories(
7+ ${CMAKE_CURRENT_SOURCE_DIR}
8+ ${CMAKE_CURRENT_BINARY_DIR}
9+ ${Qt5Qml_PRIVATE_INCLUDE_DIRS}
10+ ${Qt5Quick_INCLUDE_DIRS}
11+ ${Qt5Quick_PRIVATE_INCLUDE_DIRS}
12+ ${Qt5V8_PRIVATE_INCLUDE_DIR}
13+)
14+
15+remove_definitions(-DQT_NO_KEYWORDS)
16+
17+set(QMLPLUGIN_SRC
18+ plugin.cpp
19+ listviewwithpageheader.cpp
20+ )
21+
22+add_library(ListViewWithPageHeader-qml MODULE
23+ ${QMLPLUGIN_SRC}
24+ )
25+
26+target_link_libraries(ListViewWithPageHeader-qml
27+ ${Qt5Gui_LIBRARIES}
28+ ${Qt5Quick_LIBRARIES}
29+ )
30+
31+qt5_use_modules(ListViewWithPageHeader-qml Qml Quick)
32+
33+# copy qmldir file into build directory for shadow builds
34+file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
35+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
36+ )
37+
38+install(TARGETS ListViewWithPageHeader-qml
39+ DESTINATION ${SHELL_APP_DIR}/plugins/ListViewWithPageHeader
40+ )
41+
42+install(FILES qmldir
43+ DESTINATION ${SHELL_APP_DIR}/plugins/ListViewWithPageHeader
44+ )
plugins/ListViewWithPageHeader/listviewwithpageheader.cppnew file+1059
@@ -0,0 +1,1059 @@
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+/*
18+ * Some documentation on how this thing works:
19+ *
20+ * A flickable has two very important concepts that define the top and
21+ * height of the flickable area.
22+ * The top is returned in minYExtent()
23+ * The height is set using setContentHeight()
24+ * By changing those two values we can make the list grow up or down
25+ * as needed. e.g. if we are in the middle of the list
26+ * and something that is above the viewport grows, since we do not
27+ * want to change the viewport because of that we just adjust the
28+ * minYExtent so that the list grows up.
29+ *
30+ * The implementation on the list relies on the delegateModel doing
31+ * most of the instantiation work. You call createItem() when you
32+ * need to create an item asking for it async or not. If returns null
33+ * it means the item will be created async and the model will call the
34+ * itemCreated slot with the item.
35+ *
36+ * updatePolish is the central point of dispatch for the work of the
37+ * class. It is called by the scene graph just before drawing the class.
38+ * In it we:
39+ * * Make sure all items are positioned correctly
40+ * * Add/Remove items if needed
41+ * * Update the content height if it was dirty
42+ *
43+ * m_visibleItems contains all the items we have created at the moment.
44+ * Actually not all of them are visible since it includes the ones
45+ * in the cache area we create asynchronously to help performance.
46+ * The first item in m_visibleItems has the m_firstVisibleIndex in
47+ * the model. If you actually want to know what is the first
48+ * item in the viewport you have to find the first non culled element
49+ * in m_visibleItems
50+ *
51+ * All the items (except the header) are childs of m_clipItem which
52+ * is a child of the contentItem() of the flickable (The contentItem()
53+ * is what actually 'moves' in a a flickable). This way
54+ * we can implement the clipping needed so we can have the header
55+ * shown in the middle of the list over the items without the items
56+ * leaking under the header in case it is transparent.
57+ *
58+ * The first item of m_visibleItems is the one that defines the
59+ * positions of all the rest of items (see updatePolish()) and
60+ * this is why sometimes we move it even if it's not the item
61+ * that has triggered the function (i.e. in itemGeometryChanged())
62+ *
63+ * m_visibleItems is a list of ListItem. Each ListItem
64+ * will contain a item and potentially a sectionItem. The sectionItem
65+ * is only there when the list is using sectionDelegate+sectionProperty
66+ * and this is the first item of the section. Each ListItem is vertically
67+ * layouted with the sectionItem first and then the item.
68+ *
69+ * For sectioning we also have a section item alone (m_topSectionItem)
70+ * that is used for the cases we need to show the sticky section item at
71+ * the top of the view.
72+ *
73+ * Each delegate item has a context property called heightToClip that is
74+ * used to communicate to the delegate implementation in case it has to
75+ * clip itself because of overlapping with the top sticky section item.
76+ * This is an implementation decision since it has been agreed it
77+ * is easier to implement the clipping in QML with this info than to
78+ * do it at the C++ level.
79+ *
80+ * Note that minYExtent and height are not always totally accurate, since
81+ * we don't have the items created we can't guess their heights
82+ * so we can only guarantee the values are correct when the first/last
83+ * items of the list are visible, otherwise we just live with good enough
84+ * values that make the list scrollable
85+ *
86+ * There are a few things that are not really implemented or tested properly
87+ * which we don't use at the moment like changing the model, changing
88+ * the section delegate, having a section delegate that changes its size, etc.
89+ * The known missing features are marked with TODOs along the code.
90+ */
91+
92+#include "listviewwithpageheader.h"
93+
94+#include <QDebug>
95+#include <qqmlinfo.h>
96+#include <qqmlengine.h>
97+#include <private/qquickvisualdatamodel_p.h>
98+#include <private/qqmlglobal_p.h>
99+#include <private/qquickitem_p.h>
100+#include <private/qquickanimation_p.h>
101+// #include <private/qquickrectangle_p.h>
102+
103+static const qreal bufferRatio = 0.5;
104+
105+qreal ListViewWithPageHeader::ListItem::height() const
106+{
107+ return m_item->height() + (m_sectionItem ? m_sectionItem->height() : 0);
108+}
109+
110+qreal ListViewWithPageHeader::ListItem::y() const
111+{
112+ return m_item->y() - (m_sectionItem ? m_sectionItem->height() : 0);
113+}
114+
115+void ListViewWithPageHeader::ListItem::setY(qreal newY)
116+{
117+ if (m_sectionItem) {
118+ m_sectionItem->setY(newY);
119+ m_item->setY(newY + m_sectionItem->height());
120+ } else {
121+ m_item->setY(newY);
122+ }
123+}
124+
125+bool ListViewWithPageHeader::ListItem::culled() const
126+{
127+ return QQuickItemPrivate::get(m_item)->culled;
128+}
129+
130+void ListViewWithPageHeader::ListItem::setCulled(bool culled)
131+{
132+ QQuickItemPrivate::get(m_item)->setCulled(culled);
133+ if (m_sectionItem)
134+ QQuickItemPrivate::get(m_sectionItem)->setCulled(culled);
135+}
136+
137+ListViewWithPageHeader::ListViewWithPageHeader()
138+ : m_delegateModel(nullptr)
139+ , m_asyncRequestedIndex(-1)
140+ , m_delegateValidated(false)
141+ , m_firstVisibleIndex(-1)
142+ , m_minYExtent(0)
143+ , m_contentHeightDirty(false)
144+ , m_headerItem(nullptr)
145+ , m_previousContentY(0)
146+ , m_headerItemShownHeight(0)
147+ , m_sectionDelegate(nullptr)
148+ , m_topSectionItem(nullptr)
149+ , m_forceNoClip(false)
150+ , m_inLayout(false)
151+{
152+ m_clipItem = new QQuickItem(contentItem());
153+// m_clipItem = new QQuickRectangle(contentItem());
154+// ((QQuickRectangle*)m_clipItem)->setColor(Qt::gray);
155+
156+ m_headerShowAnimation = new QQuickNumberAnimation(this);
157+ m_headerShowAnimation->setEasing(QEasingCurve::OutQuad);
158+ m_headerShowAnimation->setProperty("contentY");
159+ m_headerShowAnimation->setDuration(200);
160+ m_headerShowAnimation->setTargetObject(this);
161+
162+ connect(this, SIGNAL(contentWidthChanged()), this, SLOT(onContentWidthChanged()));
163+ connect(this, SIGNAL(contentHeightChanged()), this, SLOT(onContentHeightChanged()));
164+ connect(this, SIGNAL(heightChanged()), this, SLOT(onHeightChanged()));
165+ connect(m_headerShowAnimation, SIGNAL(stopped()), this, SLOT(onShowHeaderAnimationFinished()));
166+}
167+
168+ListViewWithPageHeader::~ListViewWithPageHeader()
169+{
170+}
171+
172+QAbstractItemModel *ListViewWithPageHeader::model() const
173+{
174+ return m_delegateModel ? m_delegateModel->model().value<QAbstractItemModel *>() : nullptr;
175+}
176+
177+void ListViewWithPageHeader::setModel(QAbstractItemModel *model)
178+{
179+ if (model != this->model()) {
180+ if (!m_delegateModel) {
181+ createDelegateModel();
182+ } else {
183+ disconnect(m_delegateModel, SIGNAL(modelUpdated(QQuickChangeSet,bool)), this, SLOT(onModelUpdated(QQuickChangeSet,bool)));
184+ }
185+ m_delegateModel->setModel(QVariant::fromValue<QAbstractItemModel *>(model));
186+ connect(m_delegateModel, SIGNAL(modelUpdated(QQuickChangeSet,bool)), this, SLOT(onModelUpdated(QQuickChangeSet,bool)));
187+ Q_EMIT modelChanged();
188+ // TODO?
189+// Q_EMIT contentHeightChanged();
190+// Q_EMIT contentYChanged();
191+ }
192+}
193+
194+QQmlComponent *ListViewWithPageHeader::delegate() const
195+{
196+ return m_delegateModel ? m_delegateModel->delegate() : nullptr;
197+}
198+
199+void ListViewWithPageHeader::setDelegate(QQmlComponent *delegate)
200+{
201+ if (delegate != this->delegate()) {
202+ if (!m_delegateModel) {
203+ createDelegateModel();
204+ }
205+
206+ // Cleanup the existing items
207+ Q_FOREACH(ListItem *item, m_visibleItems)
208+ releaseItem(item);
209+ m_visibleItems.clear();
210+ m_firstVisibleIndex = -1;
211+ adjustMinYExtent();
212+ setContentY(0);
213+ m_clipItem->setY(0);
214+ if (m_topSectionItem) {
215+ QQuickItemPrivate::get(m_topSectionItem)->setCulled(true);
216+ }
217+
218+ m_delegateModel->setDelegate(delegate);
219+
220+ Q_EMIT delegateChanged();
221+ m_delegateValidated = false;
222+ m_contentHeightDirty = true;
223+ polish();
224+ }
225+}
226+
227+QQuickItem *ListViewWithPageHeader::header() const
228+{
229+ return m_headerItem;
230+}
231+
232+void ListViewWithPageHeader::setHeader(QQuickItem *headerItem)
233+{
234+ if (m_headerItem != headerItem) {
235+ qreal oldHeaderHeight = 0;
236+ qreal oldHeaderY = 0;
237+ if (m_headerItem) {
238+ oldHeaderHeight = m_headerItem->height();
239+ oldHeaderY = m_headerItem->y();
240+ m_headerItem->setParentItem(nullptr);
241+ }
242+ m_headerItem = headerItem;
243+ if (m_headerItem) {
244+ m_headerItem->setParentItem(contentItem());
245+ m_headerItem->setZ(1);
246+ }
247+ qreal newHeaderHeight = m_headerItem ? m_headerItem->height() : 0;
248+ if (!m_visibleItems.isEmpty() && newHeaderHeight != oldHeaderHeight) {
249+ headerHeightChanged(newHeaderHeight, oldHeaderHeight, oldHeaderY);
250+ polish();
251+ m_contentHeightDirty = true;
252+ }
253+ Q_EMIT headerChanged();
254+ }
255+}
256+
257+QQmlComponent *ListViewWithPageHeader::sectionDelegate() const
258+{
259+ return m_sectionDelegate;
260+}
261+
262+void ListViewWithPageHeader::setSectionDelegate(QQmlComponent *delegate)
263+{
264+ if (delegate != m_sectionDelegate) {
265+ // TODO clean existing sections
266+
267+ m_sectionDelegate = delegate;
268+
269+ m_topSectionItem = getSectionItem(QString());
270+ m_topSectionItem->setZ(3);
271+ QQuickItemPrivate::get(m_topSectionItem)->setCulled(true);
272+
273+ // TODO create sections for existing items
274+
275+ Q_EMIT sectionDelegateChanged();
276+ }
277+}
278+
279+QString ListViewWithPageHeader::sectionProperty() const
280+{
281+ return m_sectionProperty;
282+}
283+
284+void ListViewWithPageHeader::setSectionProperty(const QString &property)
285+{
286+ if (property != m_sectionProperty) {
287+ m_sectionProperty = property;
288+
289+ updateWatchedRoles();
290+
291+ // TODO recreate sections
292+
293+ Q_EMIT sectionPropertyChanged();
294+ }
295+}
296+
297+bool ListViewWithPageHeader::forceNoClip() const
298+{
299+ return m_forceNoClip;
300+}
301+
302+void ListViewWithPageHeader::setForceNoClip(bool noClip)
303+{
304+ if (noClip != m_forceNoClip) {
305+ m_forceNoClip = noClip;
306+ updateClipItem();
307+ Q_EMIT forceNoClipChanged();
308+ }
309+}
310+
311+void ListViewWithPageHeader::positionAtBeginning()
312+{
313+ qreal headerHeight = (m_headerItem ? m_headerItem->height() : 0);
314+ if (m_firstVisibleIndex != 0) {
315+ // TODO This could be optimized by trying to reuse the interesection
316+ // of items that may end up intersecting between the existing
317+ // m_visibleItems and the items we are creating in the next loop
318+ Q_FOREACH(ListItem *item, m_visibleItems)
319+ releaseItem(item);
320+ m_visibleItems.clear();
321+ m_firstVisibleIndex = -1;
322+
323+ // Create the item 0, it will be already correctly positioned at createItem()
324+ m_clipItem->setY(0);
325+ ListItem *item = createItem(0, false);
326+ // Create the subsequent items
327+ int modelIndex = 1;
328+ qreal pos = item->y() + item->height();
329+ const qreal buffer = height() * bufferRatio;
330+ const qreal bufferTo = height() + buffer;
331+ while (modelIndex < m_delegateModel->count() && pos <= bufferTo) {
332+ if (!(item = createItem(modelIndex, false)))
333+ break;
334+ pos += item->height();
335+ ++modelIndex;
336+ }
337+
338+ m_previousContentY = m_visibleItems.first()->y() - headerHeight;
339+ }
340+ setContentY(m_visibleItems.first()->y() + m_clipItem->y() - headerHeight);
341+}
342+
343+void ListViewWithPageHeader::showHeader()
344+{
345+ auto to = qMax(-minYExtent(), contentY() - m_headerItem->height() + m_headerItemShownHeight);
346+ if (to != contentY()) {
347+ m_headerShowAnimation->setTo(to);
348+ m_headerShowAnimation->start();
349+ }
350+}
351+
352+qreal ListViewWithPageHeader::minYExtent() const
353+{
354+// qDebug() << "ListViewWithPageHeader::minYExtent" << m_minYExtent;
355+ return m_minYExtent;
356+}
357+
358+void ListViewWithPageHeader::componentComplete()
359+{
360+ if (m_delegateModel)
361+ m_delegateModel->componentComplete();
362+
363+ QQuickFlickable::componentComplete();
364+
365+ polish();
366+}
367+
368+void ListViewWithPageHeader::viewportMoved(Qt::Orientations orient)
369+{
370+ QQuickFlickable::viewportMoved(orient);
371+// qDebug() << "ListViewWithPageHeader::viewportMoved" << contentY();
372+ qreal diff = m_previousContentY - contentY();
373+ if (m_headerItem) {
374+ auto oldHeaderItemShownHeight = m_headerItemShownHeight;
375+ if (contentY() < -m_minYExtent) {
376+ // Stick the header item to the top when dragging down
377+ m_headerItem->setY(contentY());
378+ m_headerItem->setHeight(m_headerItem->implicitHeight() + (-m_minYExtent - contentY()));
379+ } else {
380+ m_headerItem->setHeight(m_headerItem->implicitHeight());
381+ // We are going down (but it's not because of the rebound at the end)
382+ // (but the header was not shown by it's own position)
383+ // or the header is partially shown
384+ const bool scrolledUp = m_previousContentY > contentY();
385+ const bool notRebounding = contentY() + height() < contentHeight();
386+ const bool notShownByItsOwn = contentY() + diff > m_headerItem->y() + m_headerItem->height();
387+
388+ if (!scrolledUp && contentY() == -m_minYExtent) {
389+ m_headerItemShownHeight = 0;
390+ m_headerItem->setY(contentY());
391+ } else if ((scrolledUp && notRebounding && notShownByItsOwn) || (m_headerItemShownHeight > 0)) {
392+ m_headerItemShownHeight += diff;
393+ if (contentY() == -m_minYExtent) {
394+ m_headerItemShownHeight = 0;
395+ } else {
396+ m_headerItemShownHeight = qBound(static_cast<qreal>(0.), m_headerItemShownHeight, m_headerItem->height());
397+ }
398+ if (m_headerItemShownHeight > 0) {
399+ m_headerItem->setY(contentY() - m_headerItem->height() + m_headerItemShownHeight);
400+ } else {
401+ m_headerItem->setY(-m_minYExtent);
402+ }
403+ }
404+ }
405+ // We will be changing the clip item, need to accomadate for it
406+ // otherwise we move the firstItem down/up twice (unless the
407+ // show header animation is running, where we want to keep the viewport stable)
408+ if (!m_headerShowAnimation->isRunning()) {
409+ diff += oldHeaderItemShownHeight - m_headerItemShownHeight;
410+ } else {
411+ diff = -diff;
412+ }
413+ }
414+ if (!m_visibleItems.isEmpty()) {
415+ updateClipItem();
416+ ListItem *firstItem = m_visibleItems.first();
417+ firstItem->setY(firstItem->y() + diff);
418+ if (m_headerShowAnimation->isRunning()) {
419+ adjustMinYExtent();
420+ }
421+ }
422+
423+ m_previousContentY = contentY();
424+ layout();
425+ polish();
426+}
427+
428+void ListViewWithPageHeader::createDelegateModel()
429+{
430+ m_delegateModel = new QQuickVisualDataModel(qmlContext(this), this);
431+ connect(m_delegateModel, SIGNAL(createdItem(int,QQuickItem*)), this, SLOT(itemCreated(int,QQuickItem*)));
432+ if (isComponentComplete())
433+ m_delegateModel->componentComplete();
434+ updateWatchedRoles();
435+}
436+
437+void ListViewWithPageHeader::refill()
438+{
439+ if (m_inLayout) {
440+ return;
441+ }
442+ if (!isComponentComplete()) {
443+ return;
444+ }
445+
446+ const qreal buffer = height() * bufferRatio;
447+ const qreal from = contentY();
448+ const qreal to = from + height();
449+ const qreal bufferFrom = from - buffer;
450+ const qreal bufferTo = to + buffer;
451+
452+ bool added = addVisibleItems(from, to, false);
453+ bool removed = removeNonVisibleItems(bufferFrom, bufferTo);
454+ added |= addVisibleItems(bufferFrom, bufferTo, true);
455+
456+ if (added || removed) {
457+ m_contentHeightDirty = true;
458+ }
459+}
460+
461+bool ListViewWithPageHeader::addVisibleItems(qreal fillFrom, qreal fillTo, bool asynchronous)
462+{
463+ if (!delegate())
464+ return false;
465+
466+ if (m_delegateModel->count() == 0)
467+ return false;
468+
469+ ListItem *item;
470+// qDebug() << "ListViewWithPageHeader::addVisibleItems" << fillFrom << fillTo << asynchronous;
471+
472+ int modelIndex = 0;
473+ qreal pos = 0;
474+ if (!m_visibleItems.isEmpty()) {
475+ modelIndex = m_firstVisibleIndex + m_visibleItems.count();
476+ item = m_visibleItems.last();
477+ pos = item->y() + item->height() + m_clipItem->y();
478+ }
479+ bool changed = false;
480+// qDebug() << (modelIndex < m_delegateModel->count()) << pos << fillTo;
481+ while (modelIndex < m_delegateModel->count() && pos <= fillTo) {
482+// qDebug() << "refill: append item" << modelIndex << "pos" << pos << "asynchronous" << asynchronous;
483+ if (!(item = createItem(modelIndex, asynchronous)))
484+ break;
485+ pos += item->height();
486+ ++modelIndex;
487+ changed = true;
488+ }
489+
490+ modelIndex = 0;
491+ pos = 0;
492+ if (!m_visibleItems.isEmpty()) {
493+ modelIndex = m_firstVisibleIndex - 1;
494+ item = m_visibleItems.first();
495+ pos = item->y() + m_clipItem->y();
496+ }
497+ while (modelIndex >= 0 && pos > fillFrom) {
498+// qDebug() << "refill: prepend item" << modelIndex << "pos" << pos << "fillFrom" << fillFrom << "asynchronous" << asynchronous;
499+ if (!(item = createItem(modelIndex, asynchronous)))
500+ break;
501+ pos -= item->height();
502+ --modelIndex;
503+ changed = true;
504+ }
505+
506+ return changed;
507+}
508+
509+void ListViewWithPageHeader::reallyReleaseItem(ListItem *listItem)
510+{
511+ QQuickItem *item = listItem->m_item;
512+ QQuickVisualModel::ReleaseFlags flags = m_delegateModel->release(item);
513+ if (flags & QQuickVisualModel::Destroyed) {
514+ item->setParentItem(nullptr);
515+ }
516+ delete listItem->m_sectionItem;
517+ delete listItem;
518+}
519+
520+void ListViewWithPageHeader::releaseItem(ListItem *listItem)
521+{
522+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(listItem->m_item);
523+ itemPrivate->removeItemChangeListener(this, QQuickItemPrivate::Geometry);
524+ m_itemsToRelease << listItem;
525+}
526+
527+void ListViewWithPageHeader::updateWatchedRoles()
528+{
529+ if (m_delegateModel) {
530+ QList<QByteArray> roles;
531+ if (!m_sectionProperty.isEmpty())
532+ roles << m_sectionProperty.toUtf8();
533+ m_delegateModel->setWatchedRoles(roles);
534+ }
535+}
536+
537+QQuickItem *ListViewWithPageHeader::getSectionItem(int modelIndex, bool alreadyInserted)
538+{
539+ if (!m_sectionDelegate)
540+ return nullptr;
541+
542+ const QString section = m_delegateModel->stringValue(modelIndex, m_sectionProperty);
543+ if (modelIndex > 0) {
544+ const QString prevSection = m_delegateModel->stringValue(modelIndex - 1, m_sectionProperty);
545+ if (section == prevSection)
546+ return nullptr;
547+ }
548+ if (modelIndex + 1 < model()->rowCount() && !alreadyInserted) {
549+ // Already inserted items can't steal next section header
550+ const QString nextSection = m_delegateModel->stringValue(modelIndex + 1, m_sectionProperty);
551+ if (section == nextSection) {
552+ // Steal the section header
553+ ListItem *nextItem = itemAtIndex(modelIndex); // Not +1 since not yet inserted into m_visibleItems
554+ if (nextItem) {
555+ QQuickItem *sectionItem = nextItem->m_sectionItem;
556+ nextItem->m_sectionItem = nullptr;
557+ return sectionItem;
558+ }
559+ }
560+ }
561+
562+ return getSectionItem(section);
563+}
564+
565+QQuickItem *ListViewWithPageHeader::getSectionItem(const QString &sectionText)
566+{
567+ QQuickItem *sectionItem = nullptr;
568+
569+ QQmlContext *creationContext = m_sectionDelegate->creationContext();
570+ QQmlContext *context = new QQmlContext(creationContext ? creationContext : qmlContext(this));
571+ context->setContextProperty(QLatin1String("section"), sectionText);
572+ QObject *nobj = m_sectionDelegate->beginCreate(context);
573+ if (nobj) {
574+ QQml_setParent_noEvent(context, nobj);
575+ sectionItem = qobject_cast<QQuickItem *>(nobj);
576+ if (!sectionItem) {
577+ delete nobj;
578+ } else {
579+ sectionItem->setZ(2);
580+ QQml_setParent_noEvent(sectionItem, m_clipItem);
581+ sectionItem->setParentItem(m_clipItem);
582+ }
583+ } else {
584+ delete context;
585+ }
586+ m_sectionDelegate->completeCreate();
587+
588+ // TODO attach to sectionItem so we can accomodate to it changing its height
589+
590+ return sectionItem;
591+}
592+
593+bool ListViewWithPageHeader::removeNonVisibleItems(qreal bufferFrom, qreal bufferTo)
594+{
595+// qDebug() << "ListViewWithPageHeader::removeNonVisibleItems" << bufferFrom << bufferTo;
596+ // Do not remove items if we are overshooting up or down, since we'll come back
597+ // to the "stable" position and delete/create items without any reason
598+ if (contentY() < -m_minYExtent) {
599+ return false;
600+ } else if (contentY() + height() > contentHeight()) {
601+ return false;
602+ }
603+ bool changed = false;
604+
605+ bool foundVisible = false;
606+ int i = 0;
607+ int removedItems = 0;
608+ const auto oldFirstVisibleIndex = m_firstVisibleIndex;
609+ while (i < m_visibleItems.count()) {
610+ ListItem *item = m_visibleItems[i];
611+ const qreal pos = item->y() + m_clipItem->y();
612+// qDebug() << i << pos << (pos + item->height()) << bufferFrom << bufferTo;
613+ if (pos + item->height() < bufferFrom || pos > bufferTo) {
614+// qDebug() << "Releasing" << i << (pos + item->height() < bufferFrom) << pos + item->height() << bufferFrom << (pos > bufferTo) << pos << bufferTo;
615+ releaseItem(item);
616+ m_visibleItems.removeAt(i);
617+ changed = true;
618+ ++removedItems;
619+ } else {
620+ if (!foundVisible) {
621+ foundVisible = true;
622+ const int itemIndex = m_firstVisibleIndex + removedItems + i;
623+ m_firstVisibleIndex = itemIndex;
624+ }
625+ ++i;
626+ }
627+ }
628+ if (m_firstVisibleIndex != oldFirstVisibleIndex) {
629+ adjustMinYExtent();
630+ }
631+
632+ return changed;
633+}
634+
635+ListViewWithPageHeader::ListItem *ListViewWithPageHeader::createItem(int modelIndex, bool asynchronous)
636+{
637+// qDebug() << "CREATE ITEM" << modelIndex;
638+ if (asynchronous && m_asyncRequestedIndex != -1)
639+ return nullptr;
640+
641+ m_asyncRequestedIndex = -1;
642+ QQuickItem *item = m_delegateModel->item(modelIndex, asynchronous);
643+ if (!item) {
644+ m_asyncRequestedIndex = modelIndex;
645+ return 0;
646+ } else {
647+// qDebug() << "ListViewWithPageHeader::createItem::We have the item" << modelIndex << item;
648+ ListItem *listItem = new ListItem;
649+ listItem->m_item = item;
650+ listItem->m_sectionItem = getSectionItem(modelIndex, false /*Not yet inserted into m_visibleItems*/);
651+ QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Geometry);
652+ ListItem *prevItem = itemAtIndex(modelIndex - 1);
653+ bool lostItem = false; // Is an item that we requested async but because of model changes
654+ // it is no longer attached to any of the existing items (has no prev nor next item)
655+ // nor is the first item
656+ if (prevItem) {
657+ listItem->setY(prevItem->y() + prevItem->height());
658+ } else {
659+ ListItem *currItem = itemAtIndex(modelIndex);
660+ if (currItem) {
661+ // There's something already in m_visibleItems at out index, meaning this is an insert, so attach to its top
662+ listItem->setY(currItem->y() - listItem->height());
663+ } else {
664+ ListItem *nextItem = itemAtIndex(modelIndex + 1);
665+ if (nextItem) {
666+ listItem->setY(nextItem->y() - listItem->height());
667+ } else if (modelIndex == 0 && m_headerItem) {
668+ listItem->setY(m_headerItem->height());
669+ } else if (!m_visibleItems.isEmpty()) {
670+ lostItem = true;
671+ }
672+ }
673+ }
674+ if (lostItem) {
675+ releaseItem(listItem);
676+ listItem = nullptr;
677+ } else {
678+ listItem->setCulled(listItem->y() + listItem->height() + m_clipItem->y() < contentY() || listItem->y() + m_clipItem->y() >= contentY() + height());
679+ if (m_visibleItems.isEmpty()) {
680+ m_visibleItems << listItem;
681+ } else {
682+ m_visibleItems.insert(modelIndex - m_firstVisibleIndex, listItem);
683+ }
684+ if (m_firstVisibleIndex < 0 || modelIndex < m_firstVisibleIndex) {
685+ m_firstVisibleIndex = modelIndex;
686+ polish();
687+ }
688+ adjustMinYExtent();
689+ m_contentHeightDirty = true;
690+ }
691+ return listItem;
692+ }
693+}
694+
695+void ListViewWithPageHeader::itemCreated(int modelIndex, QQuickItem *item)
696+{
697+// qDebug() << "ListViewWithPageHeader::itemCreated" << modelIndex << item;
698+
699+ item->setParentItem(m_clipItem);
700+ QQmlContext *context = QQmlEngine::contextForObject(item)->parentContext();
701+ context->setContextProperty(QLatin1String("ListViewWithPageHeader"), this);
702+ context->setContextProperty(QLatin1String("heightToClip"), QVariant::fromValue<int>(0));
703+ if (modelIndex == m_asyncRequestedIndex) {
704+ createItem(modelIndex, false);
705+ refill();
706+ }
707+}
708+
709+void ListViewWithPageHeader::updateClipItem()
710+{
711+ m_clipItem->setHeight(height() - m_headerItemShownHeight);
712+ m_clipItem->setY(contentY() + m_headerItemShownHeight);
713+ m_clipItem->setClip(!m_forceNoClip && m_headerItemShownHeight > 0);
714+}
715+
716+void ListViewWithPageHeader::onContentHeightChanged()
717+{
718+ updateClipItem();
719+}
720+
721+void ListViewWithPageHeader::onContentWidthChanged()
722+{
723+ m_clipItem->setWidth(contentItem()->width());
724+}
725+
726+void ListViewWithPageHeader::onHeightChanged()
727+{
728+ polish();
729+}
730+
731+void ListViewWithPageHeader::onModelUpdated(const QQuickChangeSet &changeSet, bool /*reset*/)
732+{
733+ // TODO Do something with reset
734+// qDebug() << "ListViewWithPageHeader::onModelUpdated" << changeSet << reset;
735+ const auto oldFirstVisibleIndex = m_firstVisibleIndex;
736+
737+ Q_FOREACH(const QQuickChangeSet::Remove &remove, changeSet.removes()) {
738+// qDebug() << "ListViewWithPageHeader::onModelUpdated Remove" << remove.index << remove.count;
739+ if (remove.index + remove.count > m_firstVisibleIndex && remove.index < m_firstVisibleIndex + m_visibleItems.count()) {
740+ const qreal oldFirstValidIndexPos = m_visibleItems.first()->y();
741+ // If all the items we are removing are either not created or culled
742+ // we have to grow down to avoid viewport changing
743+ bool growDown = true;
744+ for (int i = 0; growDown && i < remove.count; ++i) {
745+ const int modelIndex = remove.index + i;
746+ ListItem *item = itemAtIndex(modelIndex);
747+ if (item && !item->culled()) {
748+ growDown = false;
749+ }
750+ }
751+ for (int i = remove.count - 1; i >= 0; --i) {
752+ const int visibleIndex = remove.index + i - m_firstVisibleIndex;
753+ if (visibleIndex >= 0 && visibleIndex < m_visibleItems.count()) {
754+ ListItem *item = m_visibleItems[visibleIndex];
755+ // Pass the section item down if needed
756+ if (item->m_sectionItem && visibleIndex + 1 < m_visibleItems.count()) {
757+ ListItem *nextItem = m_visibleItems[visibleIndex + 1];
758+ if (!nextItem->m_sectionItem) {
759+ nextItem->m_sectionItem = item->m_sectionItem;
760+ item->m_sectionItem = nullptr;
761+ }
762+ }
763+ releaseItem(item);
764+ m_visibleItems.removeAt(visibleIndex);
765+ }
766+ }
767+ if (growDown) {
768+ adjustMinYExtent();
769+ } else if (remove.index <= m_firstVisibleIndex && !m_visibleItems.isEmpty()) {
770+ // We removed the first item that is the one that positions the rest
771+ // position the new first item correctly
772+ m_visibleItems.first()->setY(oldFirstValidIndexPos);
773+ }
774+ } else if (remove.index + remove.count <= m_firstVisibleIndex) {
775+ m_firstVisibleIndex -= remove.count;
776+ }
777+ for (int i = remove.count - 1; i >= 0; --i) {
778+ const int modelIndex = remove.index + i;
779+ if (modelIndex == m_asyncRequestedIndex) {
780+ m_asyncRequestedIndex = -1;
781+ } else if (modelIndex < m_asyncRequestedIndex) {
782+ m_asyncRequestedIndex--;
783+ }
784+ }
785+ }
786+
787+ Q_FOREACH(const QQuickChangeSet::Insert &insert, changeSet.inserts()) {
788+// qDebug() << "ListViewWithPageHeader::onModelUpdated Insert" << insert.index << insert.count;
789+ const bool insertingInValidIndexes = insert.index > m_firstVisibleIndex && insert.index < m_firstVisibleIndex + m_visibleItems.count();
790+ const bool firstItemWithViewOnTop = insert.index == 0 && m_firstVisibleIndex == 0 && m_visibleItems.first()->y() + m_clipItem->y() > contentY();
791+ if (insertingInValidIndexes || firstItemWithViewOnTop)
792+ {
793+ // If the items we are adding won't be really visible
794+ // we grow up instead of down to not change the viewport
795+ bool growUp = false;
796+ if (!firstItemWithViewOnTop) {
797+ for (int i = 0; i < m_visibleItems.count(); ++i) {
798+ if (!m_visibleItems[i]->culled()) {
799+ if (insert.index <= m_firstVisibleIndex + i) {
800+ growUp = true;
801+ }
802+ break;
803+ }
804+ }
805+ }
806+
807+ const qreal oldFirstValidIndexPos = m_visibleItems.first()->y();
808+ for (int i = insert.count - 1; i >= 0; --i) {
809+ const int modelIndex = insert.index + i;
810+ ListItem *item = createItem(modelIndex, false);
811+ if (growUp) {
812+ ListItem *firstItem = m_visibleItems.first();
813+ firstItem->setY(firstItem->y() - item->height());
814+ adjustMinYExtent();
815+ }
816+ // Adding an item may break a "same section" chain, so check
817+ // if we need adding a new section item
818+ if (m_sectionDelegate) {
819+ ListItem *nextItem = itemAtIndex(modelIndex + 1);
820+ if (nextItem && !nextItem->m_sectionItem) {
821+ nextItem->m_sectionItem = getSectionItem(modelIndex + 1, true /* alredy inserted into m_visibleItems*/);
822+ if (growUp && nextItem->m_sectionItem) {
823+ ListItem *firstItem = m_visibleItems.first();
824+ firstItem->setY(firstItem->y() - nextItem->m_sectionItem->height());
825+ adjustMinYExtent();
826+ }
827+ }
828+ }
829+ }
830+ if (firstItemWithViewOnTop) {
831+ ListItem *firstItem = m_visibleItems.first();
832+ firstItem->setY(oldFirstValidIndexPos);
833+ }
834+ } else if (insert.index <= m_firstVisibleIndex) {
835+ m_firstVisibleIndex += insert.count;
836+ }
837+
838+ for (int i = insert.count - 1; i >= 0; --i) {
839+ const int modelIndex = insert.index + i;
840+ if (modelIndex <= m_asyncRequestedIndex) {
841+ m_asyncRequestedIndex++;
842+ }
843+ }
844+ }
845+
846+ if (m_firstVisibleIndex != oldFirstVisibleIndex) {
847+ adjustMinYExtent();
848+ }
849+
850+ layout();
851+ polish();
852+ m_contentHeightDirty = true;
853+}
854+
855+void ListViewWithPageHeader::onShowHeaderAnimationFinished()
856+{
857+ m_contentHeightDirty = true;
858+ polish();
859+}
860+
861+void ListViewWithPageHeader::itemGeometryChanged(QQuickItem * /*item*/, const QRectF &newGeometry, const QRectF &oldGeometry)
862+{
863+ const qreal heightDiff = newGeometry.height() - oldGeometry.height();
864+ if (heightDiff != 0) {
865+ if (oldGeometry.y() + oldGeometry.height() + m_clipItem->y() < contentY() && !m_visibleItems.isEmpty()) {
866+ ListItem *firstItem = m_visibleItems.first();
867+ firstItem->setY(firstItem->y() - heightDiff);
868+ adjustMinYExtent();
869+ layout();
870+ }
871+ refill();
872+ adjustMinYExtent();
873+ polish();
874+ m_contentHeightDirty = true;
875+ }
876+}
877+
878+void ListViewWithPageHeader::headerHeightChanged(qreal newHeaderHeight, qreal oldHeaderHeight, qreal oldHeaderY)
879+{
880+ const qreal heightDiff = newHeaderHeight - oldHeaderHeight;
881+ if (m_headerItemShownHeight > 0) {
882+ // If the header is shown because of the clip
883+ // Change its size
884+ m_headerItemShownHeight += heightDiff;
885+ m_headerItemShownHeight = qBound(static_cast<qreal>(0.), m_headerItemShownHeight, newHeaderHeight);
886+ updateClipItem();
887+ adjustMinYExtent();
888+ } else {
889+ if (oldHeaderY + oldHeaderHeight > contentY()) {
890+ // If the header is shown because its position
891+ // Change its size
892+ ListItem *firstItem = m_visibleItems.first();
893+ firstItem->setY(firstItem->y() + heightDiff);
894+ layout();
895+ } else {
896+ // If the header is not on screen, just change the start of the list
897+ // so the viewport is not changed
898+ adjustMinYExtent();
899+ }
900+ }
901+}
902+
903+
904+void ListViewWithPageHeader::adjustMinYExtent()
905+{
906+ if (m_visibleItems.isEmpty()) {
907+ m_minYExtent = 0;
908+ } else {
909+ qreal nonCreatedHeight = 0;
910+ if (m_firstVisibleIndex != 0) {
911+ // Calculate the average height of items to estimate the position of the list start
912+ const int visibleItems = m_visibleItems.count();
913+ qreal visibleItemsHeight = 0;
914+ Q_FOREACH(ListItem *item, m_visibleItems) {
915+ visibleItemsHeight += item->height();
916+ }
917+ nonCreatedHeight = m_firstVisibleIndex * visibleItemsHeight / visibleItems;
918+// qDebug() << m_firstVisibleIndex << visibleItemsHeight << visibleItems << nonCreatedHeight;
919+ }
920+ m_minYExtent = nonCreatedHeight - m_visibleItems.first()->y() - m_clipItem->y() + (m_headerItem ? m_headerItem->implicitHeight() : 0);
921+ }
922+}
923+
924+ListViewWithPageHeader::ListItem *ListViewWithPageHeader::itemAtIndex(int modelIndex) const
925+{
926+ const int visibleIndexedModelIndex = modelIndex - m_firstVisibleIndex;
927+ if (visibleIndexedModelIndex >= 0 && visibleIndexedModelIndex < m_visibleItems.count())
928+ return m_visibleItems[visibleIndexedModelIndex];
929+
930+ return nullptr;
931+}
932+
933+void ListViewWithPageHeader::layout()
934+{
935+ if (m_inLayout)
936+ return;
937+
938+ m_inLayout = true;
939+ if (!m_visibleItems.isEmpty()) {
940+ const qreal visibleFrom = contentY() - m_clipItem->y() + m_headerItemShownHeight;
941+ const qreal visibleTo = contentY() + height() - m_clipItem->y();
942+
943+ qreal pos = m_visibleItems.first()->y();
944+
945+// qDebug() << "ListViewWithPageHeader::layout Updating positions and heights. contentY" << contentY() << "minYExtent" << minYExtent();
946+ int firstReallyVisibleItem = -1;
947+ int modelIndex = m_firstVisibleIndex;
948+ Q_FOREACH(ListItem *item, m_visibleItems) {
949+ const bool cull = pos + item->height() < visibleFrom || pos >= visibleTo;
950+ item->setCulled(cull);
951+ item->setY(pos);
952+ if (!cull && firstReallyVisibleItem == -1) {
953+ firstReallyVisibleItem = modelIndex;
954+ if (m_topSectionItem) {
955+ // Update the top sticky section header
956+ const QString section = m_delegateModel->stringValue(modelIndex, m_sectionProperty);
957+ QQmlContext *context = QQmlEngine::contextForObject(m_topSectionItem)->parentContext();
958+ context->setContextProperty(QLatin1String("section"), section);
959+
960+ // Positing the top section sticky item is a two step process
961+ // First we set it either we cull it (because it doesn't need to be sticked to the top)
962+ // or stick it to the top
963+ // Then after the loop we'll make sure that if there's another section just below it
964+ // pushed the sticky section up to make it disappear
965+ const qreal topSectionStickPos = m_headerItemShownHeight + contentY() - m_clipItem->y();
966+ if (topSectionStickPos <= pos) {
967+ QQuickItemPrivate::get(m_topSectionItem)->setCulled(true);
968+ if (item->m_sectionItem) {
969+ // This seems it should happen since why would we cull the top section
970+ // if the first visible item has no section header? This only happens briefly
971+ // when increasing the height of a list that is at the bottom, the m_topSectionItem
972+ // gets shown shortly in the next polish call
973+ QQuickItemPrivate::get(item->m_sectionItem)->setCulled(false);
974+ }
975+ } else {
976+ QQuickItemPrivate::get(m_topSectionItem)->setCulled(false);
977+ m_topSectionItem->setY(topSectionStickPos);
978+ if (item->m_sectionItem) {
979+ QQuickItemPrivate::get(item->m_sectionItem)->setCulled(true);
980+ }
981+ }
982+ }
983+ }
984+ QQmlContext *context = QQmlEngine::contextForObject(item->m_item)->parentContext();
985+ const qreal clipFrom = visibleFrom + (!item->m_sectionItem && m_topSectionItem && !QQuickItemPrivate::get(m_topSectionItem)->culled ? m_topSectionItem->height() : 0);
986+ if (!cull && pos < clipFrom) {
987+ context->setContextProperty(QLatin1String("heightToClip"), clipFrom - pos);
988+ } else {
989+ context->setContextProperty(QLatin1String("heightToClip"), QVariant::fromValue<int>(0));
990+ }
991+// qDebug() << "ListViewWithPageHeader::layout" << item->m_item;
992+ pos += item->height();
993+ ++modelIndex;
994+ }
995+
996+ // Second step of section sticky item positioning
997+ // Look at the next section header, check if it's pushing up the sticky one
998+ if (m_topSectionItem) {
999+ if (firstReallyVisibleItem >= 0) {
1000+ for (int i = firstReallyVisibleItem - m_firstVisibleIndex + 1; i < m_visibleItems.count(); ++i) {
1001+ ListItem *item = m_visibleItems[i];
1002+ if (item->m_sectionItem) {
1003+ if (m_topSectionItem->y() + m_topSectionItem->height() > item->y()) {
1004+ m_topSectionItem->setY(item->y() - m_topSectionItem->height());
1005+ }
1006+ break;
1007+ }
1008+ }
1009+ }
1010+ }
1011+ }
1012+ m_inLayout = false;
1013+}
1014+
1015+void ListViewWithPageHeader::updatePolish()
1016+{
1017+ Q_FOREACH(ListItem *item, m_itemsToRelease)
1018+ reallyReleaseItem(item);
1019+ m_itemsToRelease.clear();
1020+
1021+ if (!model())
1022+ return;
1023+
1024+ layout();
1025+
1026+ refill();
1027+
1028+ if (m_contentHeightDirty) {
1029+ qreal contentHeight;
1030+ if (m_visibleItems.isEmpty()) {
1031+ contentHeight = m_headerItem ? m_headerItem->height() : 0;
1032+ } else {
1033+ const int modelCount = model()->rowCount();
1034+ const int visibleItems = m_visibleItems.count();
1035+ const int lastValidIndex = m_firstVisibleIndex + visibleItems - 1;
1036+ qreal nonCreatedHeight = 0;
1037+ if (lastValidIndex != modelCount - 1) {
1038+ const int visibleItems = m_visibleItems.count();
1039+ qreal visibleItemsHeight = 0;
1040+ Q_FOREACH(ListItem *item, m_visibleItems) {
1041+ visibleItemsHeight += item->height();
1042+ }
1043+ const int unknownSizes = modelCount - (m_firstVisibleIndex + visibleItems);
1044+ nonCreatedHeight = unknownSizes * visibleItemsHeight / visibleItems;
1045+ }
1046+ ListItem *item = m_visibleItems.last();
1047+ contentHeight = nonCreatedHeight + item->y() + item->height() + m_clipItem->y();
1048+ if (m_firstVisibleIndex != 0) {
1049+ // Make sure that if we are shrinking we tell the view we still fit
1050+ m_minYExtent = qMax(m_minYExtent, -(contentHeight - height()));
1051+ }
1052+ }
1053+
1054+ m_contentHeightDirty = false;
1055+ setContentHeight(contentHeight);
1056+ }
1057+}
1058+
1059+#include "moc_listviewwithpageheader.cpp"
plugins/ListViewWithPageHeader/listviewwithpageheader.hnew file+180
@@ -0,0 +1,180 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef LISTVIEWWITHPAGEHEADER_H
18+#define LISTVIEWWITHPAGEHEADER_H
19+
20+#include <private/qquickitemchangelistener_p.h>
21+#include <private/qquickflickable_p.h>
22+
23+class QAbstractItemModel;
24+class QQuickChangeSet;
25+class QQuickNumberAnimation;
26+class QQuickVisualDataModel;
27+
28+
29+/**
30+ Note for users of this class
31+
32+ ListViewWithPageHeader already loads delegates async when appropiate so if
33+ your delegate uses a Loader you should not enable the asynchronous feature since
34+ that will need to introduce sizing problems
35+
36+ With the double async it may happen what while we are scrolling down
37+ we reach to a point where given the size of the just created delegate with loader not yet loaded (which will be very close to 0)
38+ we are already "at the end" of the list, but then a few milliseconds later the loader finishes loading and we could
39+ have kept scrolling. This is specially visible at the end of the list where you realize
40+ that scrolling ended a bit before the end of the list but the speed of the flicking was good
41+ to reach the end
42+
43+ By not having the second async we get a better sizing when the delegate is created and things work better
44+*/
45+
46+class ListViewWithPageHeader : public QQuickFlickable, public QQuickItemChangeListener
47+{
48+ Q_OBJECT
49+ Q_PROPERTY(QAbstractItemModel *model READ model WRITE setModel NOTIFY modelChanged)
50+ Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
51+ Q_PROPERTY(QQuickItem *pageHeader READ header WRITE setHeader NOTIFY headerChanged)
52+ Q_PROPERTY(QQmlComponent *sectionDelegate READ sectionDelegate WRITE setSectionDelegate NOTIFY sectionDelegateChanged)
53+ Q_PROPERTY(QString sectionProperty READ sectionProperty WRITE setSectionProperty NOTIFY sectionPropertyChanged)
54+ Q_PROPERTY(bool forceNoClip READ forceNoClip WRITE setForceNoClip NOTIFY forceNoClipChanged)
55+
56+ friend class ListViewWithPageHeaderTest;
57+ friend class ListViewWithPageHeaderTestSection;
58+
59+public:
60+ ListViewWithPageHeader();
61+ ~ListViewWithPageHeader();
62+
63+ QAbstractItemModel *model() const;
64+ void setModel(QAbstractItemModel *model);
65+
66+ QQmlComponent *delegate() const;
67+ void setDelegate(QQmlComponent *delegate);
68+
69+ QQuickItem *header() const;
70+ void setHeader(QQuickItem *header);
71+
72+ QQmlComponent *sectionDelegate() const;
73+ void setSectionDelegate(QQmlComponent *delegate);
74+
75+ QString sectionProperty() const;
76+ void setSectionProperty(const QString &property);
77+
78+ bool forceNoClip() const;
79+ void setForceNoClip(bool noClip);
80+
81+ Q_INVOKABLE void positionAtBeginning();
82+ Q_INVOKABLE void showHeader();
83+
84+Q_SIGNALS:
85+ void modelChanged();
86+ void delegateChanged();
87+ void headerChanged();
88+ void sectionDelegateChanged();
89+ void sectionPropertyChanged();
90+ void forceNoClipChanged();
91+
92+protected:
93+ void componentComplete();
94+ void viewportMoved(Qt::Orientations orient);
95+ qreal minYExtent() const;
96+ void itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry);
97+ void updatePolish();
98+
99+private Q_SLOTS:
100+ void itemCreated(int modelIndex, QQuickItem *item);
101+ void onContentHeightChanged();
102+ void onContentWidthChanged();
103+ void onHeightChanged();
104+ void onModelUpdated(const QQuickChangeSet &changeSet, bool reset);
105+ void onShowHeaderAnimationFinished();
106+
107+private:
108+ class ListItem
109+ {
110+ public:
111+ qreal height() const;
112+
113+ qreal y() const;
114+ void setY(qreal newY);
115+
116+ bool culled() const;
117+ void setCulled(bool culled);
118+
119+ QQuickItem *m_item;
120+ QQuickItem *m_sectionItem;
121+ };
122+
123+ void createDelegateModel();
124+
125+ void layout();
126+ void refill();
127+ bool addVisibleItems(qreal fillFrom, qreal fillTo, bool asynchronous);
128+ bool removeNonVisibleItems(qreal bufferFrom, qreal bufferTo);
129+ ListItem *createItem(int modelIndex, bool asynchronous);
130+
131+ void adjustMinYExtent();
132+ void updateClipItem();
133+ void headerHeightChanged(qreal newHeaderHeight, qreal oldHeaderHeight, qreal oldHeaderY);
134+ ListItem *itemAtIndex(int modelIndex) const; // Returns the item at modelIndex if has been created
135+ void releaseItem(ListItem *item);
136+ void reallyReleaseItem(ListItem *item);
137+ void updateWatchedRoles();
138+ QQuickItem *getSectionItem(int modelIndex, bool alreadyInserted);
139+ QQuickItem *getSectionItem(const QString &sectionText);
140+
141+ QQuickVisualDataModel *m_delegateModel;
142+
143+ // Index we are waiting because we requested it asynchronously
144+ int m_asyncRequestedIndex;
145+
146+ // Used to only give a warning once if the delegate does not return objects
147+ bool m_delegateValidated;
148+
149+ // Visible indexes, [0] is m_firstValidIndex, [0+1] is m_firstValidIndex +1, ...
150+ QList<ListItem *> m_visibleItems;
151+ int m_firstVisibleIndex;
152+
153+ qreal m_minYExtent;
154+
155+ QQuickItem *m_clipItem;
156+
157+ // If any of the heights has changed
158+ // or new items have been added/removed
159+ bool m_contentHeightDirty;
160+
161+ QQuickItem *m_headerItem;
162+ qreal m_previousContentY;
163+ qreal m_headerItemShownHeight; // The height of header shown when the header is shown outside its topmost position
164+ // i.e. it's being shown after dragging down in the middle of the list
165+ QQuickNumberAnimation *m_headerShowAnimation;
166+
167+ QQmlComponent *m_sectionDelegate;
168+ QString m_sectionProperty;
169+ QQuickItem *m_topSectionItem;
170+
171+ bool m_forceNoClip;
172+ bool m_inLayout;
173+
174+ // Qt 5.0 doesn't like releasing the items just after itemCreated
175+ // so we delay the releasing until the next updatePolish
176+ QList<ListItem *> m_itemsToRelease;
177+};
178+
179+
180+#endif
plugins/ListViewWithPageHeader/plugin.cppnew file+29
@@ -0,0 +1,29 @@
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+
18+#include "plugin.h"
19+
20+#include "listviewwithpageheader.h"
21+
22+#include <QAbstractItemModel>
23+
24+void ListViewWithPageHeaderPlugin::registerTypes(const char *uri)
25+{
26+ Q_ASSERT(uri == QLatin1String("ListViewWithPageHeader"));
27+ qmlRegisterType<QAbstractItemModel>();
28+ qmlRegisterType<ListViewWithPageHeader>(uri, 0, 1, "ListViewWithPageHeader");
29+}
plugins/ListViewWithPageHeader/plugin.hnew file+33
@@ -0,0 +1,33 @@
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+
18+#ifndef LISTVIEWWITHPAGEHEADER_PLUGIN_H
19+#define LISTVIEWWITHPAGEHEADER_PLUGIN_H
20+
21+#include <QtQml/QQmlEngine>
22+#include <QtQml/QQmlExtensionPlugin>
23+
24+class ListViewWithPageHeaderPlugin : public QQmlExtensionPlugin
25+{
26+ Q_OBJECT
27+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
28+
29+public:
30+ void registerTypes(const char *uri);
31+};
32+
33+#endif
plugins/ListViewWithPageHeader/qmldirnew file+2
@@ -0,0 +1,2 @@
1+module ListViewWithPageHeader
2+plugin ListViewWithPageHeader-qml
plugins/Ubuntu/Gestures/AxisVelocityCalculator.cpp+31−16
@@ -21,9 +21,10 @@
21#include "AxisVelocityCalculator.h"
21#include "AxisVelocityCalculator.h"
22#include <QtCore/QElapsedTimer>
22#include <QtCore/QElapsedTimer>
23
23
24−class RealTimeSource : public AxisVelocityCalculator::TimeSource {
24+class RealTimeSource : public UbuntuGestures::TimeSource {
25public:
25public:
26− RealTimeSource() {
26+ RealTimeSource()
27+ : UbuntuGestures::TimeSource() {
27 m_timer.start();
28 m_timer.start();
28 }
29 }
29 virtual qint64 msecsSinceReference() {
30 virtual qint64 msecsSinceReference() {
@@ -33,23 +34,17 @@ private:
33 QElapsedTimer m_timer;
34 QElapsedTimer m_timer;
34};
35};
35
36
36−
37AxisVelocityCalculator::AxisVelocityCalculator(QObject *parent)
37AxisVelocityCalculator::AxisVelocityCalculator(QObject *parent)
38− : AxisVelocityCalculator(new RealTimeSource, parent)
39−{
40−}
41−
42−AxisVelocityCalculator::AxisVelocityCalculator(TimeSource *timeSource, QObject *parent)
43 : QObject(parent)
38 : QObject(parent)
44− , m_timeSource(timeSource)
39+ , m_timeSource(new RealTimeSource)
45 , m_trackedPosition(0.0)
40 , m_trackedPosition(0.0)
46{
41{
42+ m_timeSource->setParent(this);
47 reset();
43 reset();
48}
44}
49
45
50AxisVelocityCalculator::~AxisVelocityCalculator()
46AxisVelocityCalculator::~AxisVelocityCalculator()
51{
47{
52− delete m_timeSource;
53}
48}
54
49
55qreal AxisVelocityCalculator::trackedPosition() const
50qreal AxisVelocityCalculator::trackedPosition() const
@@ -59,13 +54,17 @@ qreal AxisVelocityCalculator::trackedPosition() const
59
54
60void AxisVelocityCalculator::setTrackedPosition(qreal newPosition)
55void AxisVelocityCalculator::setTrackedPosition(qreal newPosition)
61{
56{
57+ processMovement(newPosition - m_trackedPosition);
58+
62− if (newPosition == m_trackedPosition) {
59+ if (newPosition != m_trackedPosition) {
63− return;
60+ m_trackedPosition = newPosition;
61+ Q_EMIT trackedPositionChanged(newPosition);
64 }
62 }
63+}
65
64
65+void AxisVelocityCalculator::updateIdleTime()
66+{
66− processMovement(newPosition - m_trackedPosition);
67+ processMovement(0);
67− m_trackedPosition = newPosition;
68− Q_EMIT trackedPositionChanged(newPosition);
69}
68}
70
69
71void AxisVelocityCalculator::processMovement(qreal movement)
70void AxisVelocityCalculator::processMovement(qreal movement)
@@ -83,11 +82,12 @@ void AxisVelocityCalculator::processMovement(qreal movement)
83 m_samplesWrite = (m_samplesWrite + 1) % MAX_SAMPLES;
82 m_samplesWrite = (m_samplesWrite + 1) % MAX_SAMPLES;
84}
83}
85
84
86−qreal AxisVelocityCalculator::calculate() const
85+qreal AxisVelocityCalculator::calculate()
87{
86{
88 if (numSamples() < MIN_SAMPLES_NEEDED) {
87 if (numSamples() < MIN_SAMPLES_NEEDED) {
89 return 0.0;
88 return 0.0;
90 }
89 }
90+ updateIdleTime(); // consider the time elapsed since the last update and now
91
91
92 int lastIndex;
92 int lastIndex;
93 if (m_samplesWrite == 0) {
93 if (m_samplesWrite == 0) {
@@ -141,3 +141,18 @@ int AxisVelocityCalculator::numSamples() const
141 }
141 }
142 }
142 }
143}
143}
144+
145+void AxisVelocityCalculator::setTimeSource(UbuntuGestures::TimeSource *timeSource)
146+{
147+ if (m_timeSource && m_timeSource->parent() == this)
148+ delete m_timeSource;
149+
150+ m_timeSource = timeSource;
151+
152+ if (numSamples() > 0) {
153+ qWarning("AxisVelocityCalculator: changing time source while there are samples present.");
154+ // Any existent samples are based on the old time source and are, therefore, incompatible
155+ // with this new one.
156+ reset();
157+ }
158+}
plugins/Ubuntu/Gestures/AxisVelocityCalculator.h+31−20
@@ -25,6 +25,19 @@
25#include <stdint.h>
25#include <stdint.h>
26#include <QtCore/QObject>
26#include <QtCore/QObject>
27
27
28+namespace UbuntuGestures {
29+/*
30+ Interface for a time source.
31+ */
32+class UBUNTUGESTURES_EXPORT TimeSource : public QObject {
33+ Q_OBJECT
34+public:
35+ virtual ~TimeSource() {}
36+ /* Returns the current time in milliseconds since some reference time in the past. */
37+ virtual qint64 msecsSinceReference() = 0;
38+};
39+}
40+
28/*
41/*
29 Estimates the current velocity of a finger based on recent movement along an axis
42 Estimates the current velocity of a finger based on recent movement along an axis
30
43
@@ -59,27 +72,11 @@ class UBUNTUGESTURES_EXPORT AxisVelocityCalculator : public QObject
59 NOTIFY trackedPositionChanged)
72 NOTIFY trackedPositionChanged)
60public:
73public:
61
74
62− /*
63− Interface for a time source.
64− */
65− class TimeSource {
66− public:
67− virtual ~TimeSource() {}
68− /* Returns the current time in milliseconds since some reference time in the past. */
69− virtual qint64 msecsSinceReference() = 0;
70− };
71−
72 /*
75 /*
73 Regular constructor
76 Regular constructor
74 */
77 */
75 AxisVelocityCalculator(QObject *parent = 0);
78 AxisVelocityCalculator(QObject *parent = 0);
76
79
77− /*
78− Extended constructor useful for testing purposes where you can inject
79− a fake time source implementation.
80− */
81− AxisVelocityCalculator(TimeSource *timeSource, QObject *parent = 0);
82−
83 virtual ~AxisVelocityCalculator();
80 virtual ~AxisVelocityCalculator();
84
81
85 qreal trackedPosition() const;
82 qreal trackedPosition() const;
@@ -88,7 +85,7 @@ public:
88 /*
85 /*
89 Calculates the finger velocity, in axis units/millisecond
86 Calculates the finger velocity, in axis units/millisecond
90 */
87 */
91− Q_INVOKABLE qreal calculate() const;
88+ Q_INVOKABLE qreal calculate();
92
89
93 /*
90 /*
94 Removes all stored movements from previous calls to setTrackedPosition()
91 Removes all stored movements from previous calls to setTrackedPosition()
@@ -97,6 +94,11 @@ public:
97
94
98 int numSamples() const;
95 int numSamples() const;
99
96
97+ /*
98+ Replaces the TimeSource with the given one. Useful for testing purposes.
99+ */
100+ void setTimeSource(UbuntuGestures::TimeSource *timeSource);
101+
100 /*
102 /*
101 The minimum amount of samples needed for a velocity calculation.
103 The minimum amount of samples needed for a velocity calculation.
102 */
104 */
@@ -105,18 +107,27 @@ public:
105 /*
107 /*
106 Maximum number of movement samples stored
108 Maximum number of movement samples stored
107 */
109 */
108− static const int MAX_SAMPLES = 10;
110+ static const int MAX_SAMPLES = 50;
109
111
110 /*
112 /*
111 Age of the oldest sample considered in the velocity calculations, in
113 Age of the oldest sample considered in the velocity calculations, in
112 milliseconds, compared to the most recent one.
114 milliseconds, compared to the most recent one.
113 */
115 */
114− static const int AGE_OLDEST_SAMPLE = 200;
116+ static const int AGE_OLDEST_SAMPLE = 100;
115
117
116Q_SIGNALS:
118Q_SIGNALS:
117 void trackedPositionChanged(qreal value);
119 void trackedPositionChanged(qreal value);
118
120
119private:
121private:
122+
123+ /*
124+ Inform that trackedPosition remained motionless since the time it was
125+ last changed.
126+
127+ It's the same as calling setTrackedPosition(trackedPosition())
128+ */
129+ void updateIdleTime();
130+
120 /*
131 /*
121 How much the finger has moved since processMovement() was last called.
132 How much the finger has moved since processMovement() was last called.
122 */
133 */
@@ -134,7 +145,7 @@ private:
134 int m_samplesRead; /* index of the oldest sample available. -1 if buffer is empty */
145 int m_samplesRead; /* index of the oldest sample available. -1 if buffer is empty */
135 int m_samplesWrite; /* index where the next sample will be written */
146 int m_samplesWrite; /* index where the next sample will be written */
136
147
137− TimeSource *m_timeSource;
148+ UbuntuGestures::TimeSource *m_timeSource;
138
149
139 qreal m_trackedPosition;
150 qreal m_trackedPosition;
140};
151};
plugins/Ubuntu/Gestures/Direction.cpp+5
@@ -25,3 +25,8 @@ bool Direction::isVertical(Direction::Type type)
25{
25{
26 return type == Direction::Upwards || type == Direction::Downwards;
26 return type == Direction::Upwards || type == Direction::Downwards;
27}
27}
28+
29+bool Direction::isPositive(Direction::Type type)
30+{
31+ return type == Rightwards || type == Downwards;
32+}
plugins/Ubuntu/Gestures/Direction.h+1
@@ -38,6 +38,7 @@ public:
38
38
39 Q_INVOKABLE static bool isHorizontal(Direction::Type type);
39 Q_INVOKABLE static bool isHorizontal(Direction::Type type);
40 Q_INVOKABLE static bool isVertical(Direction::Type type);
40 Q_INVOKABLE static bool isVertical(Direction::Type type);
41+ Q_INVOKABLE static bool isPositive(Direction::Type type);
41};
42};
42
43
43#endif // DIRECTION_H
44#endif // DIRECTION_H
plugins/Ubuntu/Gestures/DirectionalDragArea.cpp+59−8
@@ -141,12 +141,9 @@ void DirectionalDragArea::setRecognitionTimer(UbuntuGestures::AbstractTimer *tim
141 }
141 }
142}
142}
143
143
144−void DirectionalDragArea::setAxisVelocityCalculator(AxisVelocityCalculator *newVelCalc)
144+void DirectionalDragArea::setTimeSource(UbuntuGestures::TimeSource *timeSource)
145{
145{
146− if (m_velocityCalculator->parent() == this)
146+ m_velocityCalculator->setTimeSource(timeSource);
147− delete m_velocityCalculator;
148−
149− m_velocityCalculator = newVelCalc;
150}
147}
151
148
152qreal DirectionalDragArea::distance() const
149qreal DirectionalDragArea::distance() const
@@ -158,6 +155,15 @@ qreal DirectionalDragArea::distance() const
158 }
155 }
159}
156}
160
157
158+qreal DirectionalDragArea::sceneDistance() const
159+{
160+ if (Direction::isHorizontal(m_direction)) {
161+ return m_previousScenePos.x() - m_startScenePos.x();
162+ } else {
163+ return m_previousScenePos.y() - m_startScenePos.y();
164+ }
165+}
166+
161qreal DirectionalDragArea::touchX() const
167qreal DirectionalDragArea::touchX() const
162{
168{
163 return m_previousPos.x();
169 return m_previousPos.x();
@@ -168,6 +174,16 @@ qreal DirectionalDragArea::touchY() const
168 return m_previousPos.y();
174 return m_previousPos.y();
169}
175}
170
176
177+qreal DirectionalDragArea::touchSceneX() const
178+{
179+ return m_previousScenePos.x();
180+}
181+
182+qreal DirectionalDragArea::touchSceneY() const
183+{
184+ return m_previousScenePos.y();
185+}
186+
171void DirectionalDragArea::touchEvent(QTouchEvent *event)
187void DirectionalDragArea::touchEvent(QTouchEvent *event)
172{
188{
173 if (!isEnabled() || !isVisible()) {
189 if (!isEnabled() || !isVisible()) {
@@ -195,15 +211,22 @@ void DirectionalDragArea::touchEvent_absent(QTouchEvent *event)
195{
211{
196 if ((event->touchPointStates() && (Qt::TouchPointPressed || Qt::TouchPointMoved))
212 if ((event->touchPointStates() && (Qt::TouchPointPressed || Qt::TouchPointMoved))
197 && event->touchPoints().count() == 1) {
213 && event->touchPoints().count() == 1) {
214+ const QTouchEvent::TouchPoint &touchPoint = event->touchPoints()[0];
198− m_startPos = event->touchPoints()[0].pos();
215+ m_startPos = touchPoint.pos();
216+ m_startScenePos = touchPoint.scenePos();
199− m_touchId = event->touchPoints()[0].id();
217+ m_touchId = touchPoint.id();
200 m_dampedPos.reset(m_startPos);
218 m_dampedPos.reset(m_startPos);
201 updateVelocityCalculator(m_startPos);
219 updateVelocityCalculator(m_startPos);
202 m_velocityCalculator->reset();
220 m_velocityCalculator->reset();
203 m_numSamplesOnLastSpeedCheck = 0;
221 m_numSamplesOnLastSpeedCheck = 0;
204 m_silenceTime = 0;
222 m_silenceTime = 0;
205 setPreviousPos(m_startPos);
223 setPreviousPos(m_startPos);
224+ setPreviousScenePos(m_startScenePos);
225+
226+ if (m_distanceThreshold > 0)
206− setStatus(Undecided);
227+ setStatus(Undecided);
228+ else
229+ setStatus(Recognized);
207 }
230 }
208}
231}
209
232
@@ -241,6 +264,7 @@ void DirectionalDragArea::touchEvent_undecided(QTouchEvent *event)
241 }
264 }
242
265
243 setPreviousPos(touchPos);
266 setPreviousPos(touchPos);
267+ setPreviousScenePos(touchPoint->scenePos());
244
268
245 if (movedFarEnough(touchPos)) {
269 if (movedFarEnough(touchPos)) {
246 setStatus(Recognized);
270 setStatus(Recognized);
@@ -252,6 +276,7 @@ void DirectionalDragArea::touchEvent_recognized(QTouchEvent *event)
252 const QTouchEvent::TouchPoint *touchPoint = fetchTargetTouchPoint(event);
276 const QTouchEvent::TouchPoint *touchPoint = fetchTargetTouchPoint(event);
253
277
254 setPreviousPos(touchPoint->pos());
278 setPreviousPos(touchPoint->pos());
279+ setPreviousScenePos(touchPoint->scenePos());
255
280
256 if (touchPoint->state() == Qt::TouchPointReleased) {
281 if (touchPoint->state() == Qt::TouchPointReleased) {
257 setStatus(WaitingForTouch);
282 setStatus(WaitingForTouch);
@@ -366,6 +391,10 @@ void DirectionalDragArea::setStatus(DirectionalDragArea::Status newStatus)
366 m_recognitionTimer->start();
391 m_recognitionTimer->start();
367 Q_EMIT draggingChanged(true);
392 Q_EMIT draggingChanged(true);
368 break;
393 break;
394+ case Recognized:
395+ if (oldStatus == WaitingForTouch)
396+ Q_EMIT draggingChanged(true);
397+ break;
369 case Rejected:
398 case Rejected:
370 Q_EMIT draggingChanged(false);
399 Q_EMIT draggingChanged(false);
371 break;
400 break;
@@ -397,6 +426,28 @@ void DirectionalDragArea::setPreviousPos(QPointF point)
397 }
426 }
398}
427}
399
428
429+void DirectionalDragArea::setPreviousScenePos(QPointF point)
430+{
431+ Q_ASSERT(m_status != Rejected);
432+
433+ bool xChanged = m_previousScenePos.x() != point.x();
434+ bool yChanged = m_previousScenePos.y() != point.y();
435+
436+ m_previousScenePos = point;
437+
438+ if (xChanged) {
439+ Q_EMIT touchSceneXChanged(point.x());
440+ if (Direction::isHorizontal(m_direction))
441+ Q_EMIT sceneDistanceChanged(sceneDistance());
442+ }
443+
444+ if (yChanged) {
445+ Q_EMIT touchSceneYChanged(point.y());
446+ if (Direction::isVertical(m_direction))
447+ Q_EMIT sceneDistanceChanged(sceneDistance());
448+ }
449+}
450+
400void DirectionalDragArea::updateVelocityCalculator(QPointF point)
451void DirectionalDragArea::updateVelocityCalculator(QPointF point)
401{
452{
402 if (Direction::isHorizontal(m_direction)) {
453 if (Direction::isHorizontal(m_direction)) {
plugins/Ubuntu/Gestures/DirectionalDragArea.h+21−3
@@ -60,10 +60,18 @@ class UBUNTUGESTURES_EXPORT DirectionalDragArea : public QQuickItem {
60 // DirectionalDragArea's direction.
60 // DirectionalDragArea's direction.
61 Q_PROPERTY(qreal distance READ distance NOTIFY distanceChanged)
61 Q_PROPERTY(qreal distance READ distance NOTIFY distanceChanged)
62
62
63+ // The distance travelled by the finger along the axis specified by
64+ // DirectionalDragArea's direction in scene coordinates
65+ Q_PROPERTY(qreal sceneDistance READ sceneDistance NOTIFY sceneDistanceChanged)
66+
63− // Position of the touch point performing the drag.
67+ // Position of the touch point performing the drag relative to this item.
64 Q_PROPERTY(qreal touchX READ touchX NOTIFY touchXChanged)
68 Q_PROPERTY(qreal touchX READ touchX NOTIFY touchXChanged)
65 Q_PROPERTY(qreal touchY READ touchY NOTIFY touchYChanged)
69 Q_PROPERTY(qreal touchY READ touchY NOTIFY touchYChanged)
66
70
71+ // Position of the touch point performing the drag, in scene's coordinate system
72+ Q_PROPERTY(qreal touchSceneX READ touchSceneX NOTIFY touchSceneXChanged)
73+ Q_PROPERTY(qreal touchSceneY READ touchSceneY NOTIFY touchSceneYChanged)
74+
67 // The current status of the directional drag gesture area.
75 // The current status of the directional drag gesture area.
68 Q_PROPERTY(Status status READ status NOTIFY statusChanged)
76 Q_PROPERTY(Status status READ status NOTIFY statusChanged)
69
77
@@ -146,10 +154,14 @@ public:
146 Status status() const { return m_status; }
154 Status status() const { return m_status; }
147
155
148 qreal distance() const;
156 qreal distance() const;
157+ qreal sceneDistance() const;
149
158
150 qreal touchX() const;
159 qreal touchX() const;
151 qreal touchY() const;
160 qreal touchY() const;
152
161
162+ qreal touchSceneX() const;
163+ qreal touchSceneY() const;
164+
153 bool dragging() const { return (m_status == Undecided) || (m_status == Recognized); }
165 bool dragging() const { return (m_status == Undecided) || (m_status == Recognized); }
154
166
155 qreal maxDeviation() const { return m_dampedPos.maxDelta(); }
167 qreal maxDeviation() const { return m_dampedPos.maxDelta(); }
@@ -172,14 +184,15 @@ public:
172 // Useful for providing a fake timer when testing.
184 // Useful for providing a fake timer when testing.
173 void setRecognitionTimer(UbuntuGestures::AbstractTimer *timer);
185 void setRecognitionTimer(UbuntuGestures::AbstractTimer *timer);
174
186
175− // Useful for testing, where a calculator with a fake time source can be supplied
187+ // Useful for testing, where a fake time source can be supplied
176− void setAxisVelocityCalculator(AxisVelocityCalculator *velCalc);
188+ void setTimeSource(UbuntuGestures::TimeSource *timeSource);
177
189
178Q_SIGNALS:
190Q_SIGNALS:
179 void directionChanged(Direction::Type direction);
191 void directionChanged(Direction::Type direction);
180 void statusChanged(Status value);
192 void statusChanged(Status value);
181 void draggingChanged(bool value);
193 void draggingChanged(bool value);
182 void distanceChanged(qreal value);
194 void distanceChanged(qreal value);
195+ void sceneDistanceChanged(qreal value);
183 void maxDeviationChanged(qreal value);
196 void maxDeviationChanged(qreal value);
184 void wideningAngleChanged(qreal value);
197 void wideningAngleChanged(qreal value);
185 void distanceThresholdChanged(qreal value);
198 void distanceThresholdChanged(qreal value);
@@ -187,6 +200,8 @@ Q_SIGNALS:
187 void maxSilenceTimeChanged(int value);
200 void maxSilenceTimeChanged(int value);
188 void touchXChanged(qreal value);
201 void touchXChanged(qreal value);
189 void touchYChanged(qreal value);
202 void touchYChanged(qreal value);
203+ void touchSceneXChanged(qreal value);
204+ void touchSceneYChanged(qreal value);
190
205
191protected:
206protected:
192 virtual void touchEvent(QTouchEvent *event);
207 virtual void touchEvent(QTouchEvent *event);
@@ -205,12 +220,15 @@ private:
205 const QTouchEvent::TouchPoint *fetchTargetTouchPoint(QTouchEvent *event);
220 const QTouchEvent::TouchPoint *fetchTargetTouchPoint(QTouchEvent *event);
206 void setStatus(Status newStatus);
221 void setStatus(Status newStatus);
207 void setPreviousPos(QPointF point);
222 void setPreviousPos(QPointF point);
223+ void setPreviousScenePos(QPointF point);
208 void updateVelocityCalculator(QPointF point);
224 void updateVelocityCalculator(QPointF point);
209
225
210 Status m_status;
226 Status m_status;
211
227
212 QPointF m_startPos;
228 QPointF m_startPos;
229+ QPointF m_startScenePos;
213 QPointF m_previousPos;
230 QPointF m_previousPos;
231+ QPointF m_previousScenePos;
214 int m_touchId;
232 int m_touchId;
215
233
216 // A movement damper is used in some of the gesture recognition calculations
234 // A movement damper is used in some of the gesture recognition calculations
po/ar.po+37−45
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-22 16:15+0000\n"
11"PO-Revision-Date: 2013-06-22 16:15+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"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-23 05:56+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
18−"X-Generator: Launchpad (build 16677)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr "متوفرة للتنزيل"
109msgid "Apps"
109msgid "Apps"
110msgstr "تطبيقات"
110msgstr "تطبيقات"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr "تطبيقات مألوفة"
114msgstr "تطبيقات مألوفة"
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr "الأشخاص المفضلون"
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr "أشخاص كانوا على اتصال مؤخرا"
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr "آخر الصوتيات المشغلة"
118msgstr "آخر الصوتيات المشغلة"
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr "فيديوهات رائجة على الإنترنت"
122msgstr "فيديوهات رائجة على الإنترنت"
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "الرئيسية"
126msgstr "الرئيسية"
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "موسيقى"
146msgstr "موسيقى"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr "المفضلات"
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr "على اتصال موخرا"
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr "أشخاص جدد"
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr "A-Z"
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "أشخاص"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr "الشائع على الإنترنت"
150msgstr "الشائع على الإنترنت"
@@ -193,7 +165,7 @@ msgstr "النجوم:"
193msgid "Author:"
165msgid "Author:"
194msgstr "المؤلف:"
166msgstr "المؤلف:"
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr "مكالمة طوارئ"
170msgstr "مكالمة طوارئ"
199
171
@@ -234,19 +206,39 @@ msgstr "الجهاز"
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr "نمط الطيران"
207msgstr "نمط الطيران"
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "ابحث"
211msgstr "ابحث"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "عذراً، لا يوجد ما يطابق بحثك."
215msgstr "عذراً، لا يوجد ما يطابق بحثك."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "الشاشة الرئيسية"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252−msgstr "رجاءً أدخِل %1:"
220+msgstr ""
221+
222+#~ msgid "People"
223+#~ msgstr "أشخاص"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "الشاشة الرئيسية"
227+
228+#~ msgid "Favourite People"
229+#~ msgstr "الأشخاص المفضلون"
230+
231+#~ msgid "People Recently in Touch"
232+#~ msgstr "أشخاص كانوا على اتصال مؤخرا"
233+
234+#~ msgid "A-Z"
235+#~ msgstr "A-Z"
236+
237+#~ msgid "Recently in touch"
238+#~ msgstr "على اتصال موخرا"
239+
240+#~ msgid "New Contacts"
241+#~ msgstr "أشخاص جدد"
242+
243+#~ msgid "Favourites"
244+#~ msgstr "المفضلات"
po/az.po+18−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Azerbaijani <az@li.org>\n"
13"Language-Team: Azerbaijani <az@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−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr ""
109msgid "Apps"
109msgid "Apps"
110msgstr "Tətbiqlər"
110msgstr "Tətbiqlər"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr ""
114msgstr ""
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr ""
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr ""
118msgstr ""
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr ""
122msgstr ""
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Ev"
126msgstr "Ev"
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "Musiqi"
146msgstr "Musiqi"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "İnsanlar"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,21 @@ msgstr ""
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr ""
207msgstr ""
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Axtar"
211msgstr "Axtar"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "Bağışlayın, amma axtarışınıza heç bir nəticə uyğun gəlmir."
215msgstr "Bağışlayın, amma axtarışınıza heç bir nəticə uyğun gəlmir."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "Əsas Ekran"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "People"
223+#~ msgstr "İnsanlar"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "Əsas Ekran"
po/bg.po+24−44
@@ -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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-19 15:47+0000\n"
11"PO-Revision-Date: 2013-06-19 15:47+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"
@@ -15,8 +15,8 @@ msgstr ""
15"MIME-Version: 1.0\n"
15"MIME-Version: 1.0\n"
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
18+"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
19−"X-Generator: Launchpad (build 16673)\n"
19+"X-Generator: Launchpad (build 16681)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
@@ -110,27 +110,19 @@ msgstr ""
110msgid "Apps"
110msgid "Apps"
111msgstr "Приложения"
111msgstr "Приложения"
112
112
113−#: Dash/DashHome.qml:43
113+#: Dash/DashHome.qml:40
114msgid "Frequent Apps"
114msgid "Frequent Apps"
115msgstr ""
115msgstr ""
116
116
117−#: Dash/DashHome.qml:46
117+#: Dash/DashHome.qml:43
118−msgid "Favourite People"
119−msgstr ""
120−
121−#: Dash/DashHome.qml:49
122−msgid "People Recently in Touch"
123−msgstr ""
124−
125−#: Dash/DashHome.qml:52
126msgid "Recent Music"
118msgid "Recent Music"
127msgstr ""
119msgstr ""
128
120
129−#: Dash/DashHome.qml:55
121+#: Dash/DashHome.qml:46
130msgid "Videos Popular Online"
122msgid "Videos Popular Online"
131msgstr ""
123msgstr ""
132
124
133−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
125+#: Dash/DashHome.qml:175
134msgid "Home"
126msgid "Home"
135msgstr "Начало"
127msgstr "Начало"
136
128
@@ -154,26 +146,6 @@ msgstr ""
154msgid "Music"
146msgid "Music"
155msgstr "Музика"
147msgstr "Музика"
156
148
157−#: Dash/DashPeople.qml:31
158−msgid "Favourites"
159−msgstr "Любими"
160−
161−#: Dash/DashPeople.qml:32
162−msgid "Recently in touch"
163−msgstr ""
164−
165−#: Dash/DashPeople.qml:33
166−msgid "New Contacts"
167−msgstr ""
168−
169−#: Dash/DashPeople.qml:34
170−msgid "A-Z"
171−msgstr "А-Я"
172−
173−#: Dash/DashPeople.qml:123
174−msgid "People"
175−msgstr "Хора"
176−
177#: Dash/DashVideos.qml:31
149#: Dash/DashVideos.qml:31
178msgid "Popular Online"
150msgid "Popular Online"
179msgstr ""
151msgstr ""
@@ -194,7 +166,7 @@ msgstr ""
194msgid "Author:"
166msgid "Author:"
195msgstr "Автор:"
167msgstr "Автор:"
196
168
197−#: Greeter/Lockscreen.qml:126
169+#: Greeter/Lockscreen.qml:133
198msgid "Emergency call"
170msgid "Emergency call"
199msgstr ""
171msgstr ""
200
172
@@ -235,19 +207,27 @@ msgstr "Устройство"
235msgid "Flight mode"
207msgid "Flight mode"
236msgstr ""
208msgstr ""
237
209
238−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
210+#: Panel/SearchIndicator.qml:26
239msgid "Search"
211msgid "Search"
240msgstr "Търсене"
212msgstr "Търсене"
241
213
242−#: plugins/Unity/lens.cpp:333
214+#: plugins/Unity/scope.cpp:268
243msgid "Sorry, there is nothing that matches your search."
215msgid "Sorry, there is nothing that matches your search."
244msgstr "Съжаляваме, няма нищо, което да отговаря на вашето търсене."
216msgstr "Съжаляваме, няма нищо, което да отговаря на вашето търсене."
245
217
246−#: plugins/Unity/lenses.cpp:39
247−msgid "Home screen"
248−msgstr "Начален екран"
249−
250−#: Shell.qml:380
218+#: Shell.qml:383
251#, qt-format
219#, qt-format
252−msgid "Please enter %1:"
220+msgid "Please enter %1"
253msgstr ""
221msgstr ""
222+
223+#~ msgid "Favourites"
224+#~ msgstr "Любими"
225+
226+#~ msgid "People"
227+#~ msgstr "Хора"
228+
229+#~ msgid "A-Z"
230+#~ msgstr "А-Я"
231+
232+#~ msgid "Home screen"
233+#~ msgstr "Начален екран"
po/ca.po+24−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Catalan <ca@li.org>\n"
13"Language-Team: Catalan <ca@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−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr "Disponibles per baixar"
109msgid "Apps"
109msgid "Apps"
110msgstr "Aplicacions"
110msgstr "Aplicacions"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr "Aplicacions freqüents"
114msgstr "Aplicacions freqüents"
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr "Gent preferida"
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr "Gent amb qui heu parlat"
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr "Música recent"
118msgstr "Música recent"
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr "Vídeos populars en línia"
122msgstr "Vídeos populars en línia"
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Inici"
126msgstr "Inici"
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "Música"
146msgstr "Música"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "Gent"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,27 @@ msgstr "Dispositiu"
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr "Mode d'avió"
207msgstr "Mode d'avió"
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Cerca"
211msgstr "Cerca"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "No hi ha res que coincideixi amb la cerca"
215msgstr "No hi ha res que coincideixi amb la cerca"
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "Pantalla d'inici"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "People"
223+#~ msgstr "Gent"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "Pantalla d'inici"
227+
228+#~ msgid "Favourite People"
229+#~ msgstr "Gent preferida"
230+
231+#~ msgid "People Recently in Touch"
232+#~ msgstr "Gent amb qui heu parlat"
po/de.po+38−46
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-23 18:17+0000\n"
11+"PO-Revision-Date: 2013-06-29 12:53+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"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-24 05:27+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-30 07:12+0000\n"
18−"X-Generator: Launchpad (build 16677)\n"
18+"X-Generator: Launchpad (build 16692)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr "Zum Herunterladen verfügbar"
109msgid "Apps"
109msgid "Apps"
110msgstr "Anwendungen"
110msgstr "Anwendungen"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr "Häufig genutzte Anwendungen"
114msgstr "Häufig genutzte Anwendungen"
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr "Lieblingspersonen"
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr "Zuletzt kontaktierte Personen"
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr "Zuletzt gehörte Musik"
118msgstr "Zuletzt gehörte Musik"
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr "Beliebte Online-Videos"
122msgstr "Beliebte Online-Videos"
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Start"
126msgstr "Start"
135
127
@@ -153,26 +145,6 @@ msgstr "Top Tabellenplatz"
153msgid "Music"
145msgid "Music"
154msgstr "Musik"
146msgstr "Musik"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr "Favoriten"
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr "Kürzlich im Gespräch"
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr "Neue Kontakte"
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr "A-Z"
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "Personen"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr "Online Beliebt"
150msgstr "Online Beliebt"
@@ -193,7 +165,7 @@ msgstr "Darsteller:"
193msgid "Author:"
165msgid "Author:"
194msgstr "Autor:"
166msgstr "Autor:"
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr "Notruf"
170msgstr "Notruf"
199
171
@@ -234,19 +206,39 @@ msgstr "Gerät"
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr "Flugmodus"
207msgstr "Flugmodus"
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Suchen"
211msgstr "Suchen"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "Entschuldigung, es wurden keine Treffer erzielt."
215msgstr "Entschuldigung, es wurden keine Treffer erzielt."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "Startseite"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252−msgstr "Bitte geben Sie %1 ein:"
220+msgstr "Bitte geben Sie %1 ein"
221+
222+#~ msgid "People"
223+#~ msgstr "Personen"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "Startseite"
227+
228+#~ msgid "Favourite People"
229+#~ msgstr "Lieblingspersonen"
230+
231+#~ msgid "People Recently in Touch"
232+#~ msgstr "Zuletzt kontaktierte Personen"
233+
234+#~ msgid "A-Z"
235+#~ msgstr "A-Z"
236+
237+#~ msgid "Recently in touch"
238+#~ msgstr "Kürzlich im Gespräch"
239+
240+#~ msgid "New Contacts"
241+#~ msgstr "Neue Kontakte"
242+
243+#~ msgid "Favourites"
244+#~ msgstr "Favoriten"
po/el.po+18−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Greek <el@li.org>\n"
13"Language-Team: Greek <el@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−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr ""
109msgid "Apps"
109msgid "Apps"
110msgstr "Εφαρμογές"
110msgstr "Εφαρμογές"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr ""
114msgstr ""
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr ""
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr ""
118msgstr ""
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr ""
122msgstr ""
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Αρχή"
126msgstr "Αρχή"
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "Μουσική"
146msgstr "Μουσική"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "Πρόσωπα"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,21 @@ msgstr ""
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr ""
207msgstr ""
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Αναζήτηση"
211msgstr "Αναζήτηση"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "Λυπούμαστε, δεν υπάρχει τίποτα που να ταιριάζει στην αναζήτησή σας."
215msgstr "Λυπούμαστε, δεν υπάρχει τίποτα που να ταιριάζει στην αναζήτησή σας."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "Αρχική οθόνη"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "People"
223+#~ msgstr "Πρόσωπα"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "Αρχική οθόνη"
po/en_AU.po+36−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-18 20:36+0000\n"
11"PO-Revision-Date: 2013-06-18 20:36+0000\n"
12"Last-Translator: Jackson Doak <Doak.jackson@gmail.com>\n"
12"Last-Translator: Jackson Doak <Doak.jackson@gmail.com>\n"
13"Language-Team: English (Australia) <en_AU@li.org>\n"
13"Language-Team: English (Australia) <en_AU@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−"X-Launchpad-Export-Date: 2013-06-20 06:37+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr "Available for download"
109msgid "Apps"
109msgid "Apps"
110msgstr "Apps"
110msgstr "Apps"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr "Frequent Apps"
114msgstr "Frequent Apps"
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr "Favourite People"
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr "People Recently in Touch"
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr "Recent Music"
118msgstr "Recent Music"
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr "Videos Popular Online"
122msgstr "Videos Popular Online"
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Home"
126msgstr "Home"
135
127
@@ -153,26 +145,6 @@ msgstr "Top Charting"
153msgid "Music"
145msgid "Music"
154msgstr "Music"
146msgstr "Music"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr "Favourites"
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr "Recently in touch"
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr "New Contacts"
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr "A-Z"
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "People"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr "Popular Online"
150msgstr "Popular Online"
@@ -193,7 +165,7 @@ msgstr "Starring:"
193msgid "Author:"
165msgid "Author:"
194msgstr "Author:"
166msgstr "Author:"
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,39 @@ msgstr "Device"
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr "Flight mode"
207msgstr "Flight mode"
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Search"
211msgstr "Search"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "Sorry, there is nothing that matches your search."
215msgstr "Sorry, there is nothing that matches your search."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "Home screen"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "People"
223+#~ msgstr "People"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "Home screen"
227+
228+#~ msgid "Favourite People"
229+#~ msgstr "Favourite People"
230+
231+#~ msgid "People Recently in Touch"
232+#~ msgstr "People Recently in Touch"
233+
234+#~ msgid "A-Z"
235+#~ msgstr "A-Z"
236+
237+#~ msgid "Recently in touch"
238+#~ msgstr "Recently in touch"
239+
240+#~ msgid "New Contacts"
241+#~ msgstr "New Contacts"
242+
243+#~ msgid "Favourites"
244+#~ msgstr "Favourites"
po/en_GB.po+38−46
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-23 22:34+0000\n"
11+"PO-Revision-Date: 2013-06-27 00:22+0000\n"
12"Last-Translator: Andi Chandler <Unknown>\n"
12"Last-Translator: Andi Chandler <Unknown>\n"
13"Language-Team: English (United Kingdom) <en_GB@li.org>\n"
13"Language-Team: English (United Kingdom) <en_GB@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−"X-Launchpad-Export-Date: 2013-06-24 05:27+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16677)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr "Available for download"
109msgid "Apps"
109msgid "Apps"
110msgstr "Apps"
110msgstr "Apps"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr "Frequent Apps"
114msgstr "Frequent Apps"
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr "Favourite People"
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr "People Recently in Touch"
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr "Recent Music"
118msgstr "Recent Music"
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr "Videos Popular Online"
122msgstr "Videos Popular Online"
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Home"
126msgstr "Home"
135
127
@@ -153,26 +145,6 @@ msgstr "Top Charting"
153msgid "Music"
145msgid "Music"
154msgstr "Music"
146msgstr "Music"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr "Favourites"
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr "Recently in touch"
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr "New Contacts"
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr "A-Z"
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "People"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr "Popular Online"
150msgstr "Popular Online"
@@ -193,7 +165,7 @@ msgstr "Starring:"
193msgid "Author:"
165msgid "Author:"
194msgstr "Author:"
166msgstr "Author:"
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr "Emergency call"
170msgstr "Emergency call"
199
171
@@ -234,19 +206,39 @@ msgstr "Device"
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr "Flight mode"
207msgstr "Flight mode"
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Search"
211msgstr "Search"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "Sorry, there is nothing that matches your search."
215msgstr "Sorry, there is nothing that matches your search."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "Home screen"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252−msgstr "Please enter %1:"
220+msgstr "Please enter %1"
221+
222+#~ msgid "Favourite People"
223+#~ msgstr "Favourite People"
224+
225+#~ msgid "People Recently in Touch"
226+#~ msgstr "People Recently in Touch"
227+
228+#~ msgid "People"
229+#~ msgstr "People"
230+
231+#~ msgid "A-Z"
232+#~ msgstr "A-Z"
233+
234+#~ msgid "Recently in touch"
235+#~ msgstr "Recently in touch"
236+
237+#~ msgid "New Contacts"
238+#~ msgstr "New Contacts"
239+
240+#~ msgid "Favourites"
241+#~ msgstr "Favourites"
242+
243+#~ msgid "Home screen"
244+#~ msgstr "Home screen"
po/eo.po+12−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11"PO-Revision-Date: 2013-06-05 22:20+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"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr ""
109msgid "Apps"
109msgid "Apps"
110msgstr ""
110msgstr ""
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr ""
114msgstr ""
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr ""
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr ""
118msgstr ""
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr ""
122msgstr ""
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr ""
126msgstr ""
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr ""
146msgstr ""
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr ""
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,15 @@ msgstr ""
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr ""
207msgstr ""
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr ""
211msgstr ""
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr ""
215msgstr ""
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr ""
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
po/es.po+36−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-16 23:44+0000\n"
11"PO-Revision-Date: 2013-06-16 23:44+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−"X-Launchpad-Export-Date: 2013-06-20 06:37+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr "Disponibles para descargar"
109msgid "Apps"
109msgid "Apps"
110msgstr "Aplicaciones"
110msgstr "Aplicaciones"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr "Aplicaciones frecuentes"
114msgstr "Aplicaciones frecuentes"
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr "Gente favorita"
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr "Gente contactada recientemente"
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr "Música reciente"
118msgstr "Música reciente"
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr "Vídeos populares en línea"
122msgstr "Vídeos populares en línea"
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Inicio"
126msgstr "Inicio"
135
127
@@ -153,26 +145,6 @@ msgstr "Mejor posicionadas"
153msgid "Music"
145msgid "Music"
154msgstr "Música"
146msgstr "Música"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr "Favoritos"
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr "Contactados recientemente"
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr "Contactos nuevos"
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr "A-Z"
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "Gente"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr "Populares en línea"
150msgstr "Populares en línea"
@@ -193,7 +165,7 @@ msgstr "Protagonistas:"
193msgid "Author:"
165msgid "Author:"
194msgstr "Autor:"
166msgstr "Autor:"
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,39 @@ msgstr "Dispositivo"
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr "Modo de vuelo"
207msgstr "Modo de vuelo"
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Buscar"
211msgstr "Buscar"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "No hay nada que coincida con su búsqueda."
215msgstr "No hay nada que coincida con su búsqueda."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "Pantalla de inicio"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "People"
223+#~ msgstr "Gente"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "Pantalla de inicio"
227+
228+#~ msgid "Favourite People"
229+#~ msgstr "Gente favorita"
230+
231+#~ msgid "People Recently in Touch"
232+#~ msgstr "Gente contactada recientemente"
233+
234+#~ msgid "Recently in touch"
235+#~ msgstr "Contactados recientemente"
236+
237+#~ msgid "Favourites"
238+#~ msgstr "Favoritos"
239+
240+#~ msgid "A-Z"
241+#~ msgstr "A-Z"
242+
243+#~ msgid "New Contacts"
244+#~ msgstr "Contactos nuevos"
po/fi.po+33−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-10 16:19+0000\n"
11"PO-Revision-Date: 2013-06-10 16:19+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−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr "Ladattavissa"
109msgid "Apps"
109msgid "Apps"
110msgstr "Sovellukset"
110msgstr "Sovellukset"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr "Yleisimmät sovellukset"
114msgstr "Yleisimmät sovellukset"
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr "Suosikkihenkilöt"
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr "Viimeksi yhteydessä olleet henkilöt"
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr "Viimeisin musiikki"
118msgstr "Viimeisin musiikki"
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr "Suositut verkkovideot"
122msgstr "Suositut verkkovideot"
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Kotinäyttö"
126msgstr "Kotinäyttö"
135
127
@@ -153,26 +145,6 @@ msgstr "Nousukiidossa"
153msgid "Music"
145msgid "Music"
154msgstr "Musiikki"
146msgstr "Musiikki"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr "Suosikit"
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr "Viimeksi yhteydessä"
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr "Uudet yhteystiedot"
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "Ihmiset"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr "Suosittua verkossa"
150msgstr "Suosittua verkossa"
@@ -193,7 +165,7 @@ msgstr "Pääosissa:"
193msgid "Author:"
165msgid "Author:"
194msgstr "Laatinut:"
166msgstr "Laatinut:"
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,36 @@ msgstr "Laite"
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr "Lentokonetila"
207msgstr "Lentokonetila"
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Hae"
211msgstr "Hae"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "Hakuun täsmääviä tuloksia ei löydy."
215msgstr "Hakuun täsmääviä tuloksia ei löydy."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "Kotinäyttö"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "People"
223+#~ msgstr "Ihmiset"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "Kotinäyttö"
227+
228+#~ msgid "Favourite People"
229+#~ msgstr "Suosikkihenkilöt"
230+
231+#~ msgid "People Recently in Touch"
232+#~ msgstr "Viimeksi yhteydessä olleet henkilöt"
233+
234+#~ msgid "Favourites"
235+#~ msgstr "Suosikit"
236+
237+#~ msgid "Recently in touch"
238+#~ msgstr "Viimeksi yhteydessä"
239+
240+#~ msgid "New Contacts"
241+#~ msgstr "Uudet yhteystiedot"
po/fo.po+18−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Faroese <fo@li.org>\n"
13"Language-Team: Faroese <fo@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−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr ""
109msgid "Apps"
109msgid "Apps"
110msgstr "Nýtsluskipanir"
110msgstr "Nýtsluskipanir"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr ""
114msgstr ""
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr ""
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr ""
118msgstr ""
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr ""
122msgstr ""
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Heim"
126msgstr "Heim"
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "Tónleikur"
146msgstr "Tónleikur"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "Fólk"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,21 @@ msgstr ""
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr ""
207msgstr ""
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Leita"
211msgstr "Leita"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "Tíanverri er tað einki sum hóskar til tína leiting."
215msgstr "Tíanverri er tað einki sum hóskar til tína leiting."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "Heimaskíggi"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "People"
223+#~ msgstr "Fólk"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "Heimaskíggi"
po/fr.po+71−82
@@ -7,63 +7,63 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11+"PO-Revision-Date: 2013-06-26 15:11+0000\n"
12−"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12+"Last-Translator: Anne <anneonyme017@gmail.com>\n"
13"Language-Team: French <fr@li.org>\n"
13"Language-Team: French <fr@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−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
22−msgstr ""
22+msgstr "Téléphone"
23
23
24#: Applications/applications.js:29
24#: Applications/applications.js:29
25msgid "Camera"
25msgid "Camera"
26−msgstr ""
26+msgstr "Appareil photo"
27
27
28#: Applications/applications.js:35
28#: Applications/applications.js:35
29msgid "Gallery"
29msgid "Gallery"
30−msgstr ""
30+msgstr "Galerie"
31
31
32#: Applications/applications.js:40
32#: Applications/applications.js:40
33msgid "Facebook"
33msgid "Facebook"
34−msgstr ""
34+msgstr "Facebook"
35
35
36#: Applications/applications.js:46
36#: Applications/applications.js:46
37msgid "Browser"
37msgid "Browser"
38−msgstr ""
38+msgstr "Navigateur"
39
39
40#: Applications/applications.js:51
40#: Applications/applications.js:51
41msgid "Twitter"
41msgid "Twitter"
42−msgstr ""
42+msgstr "Twitter"
43
43
44#: Applications/applications.js:57
44#: Applications/applications.js:57
45msgid "GMail"
45msgid "GMail"
46−msgstr ""
46+msgstr "GMail"
47
47
48#: Applications/applications.js:62
48#: Applications/applications.js:62
49msgid "Weather"
49msgid "Weather"
50−msgstr ""
50+msgstr "Météo"
51
51
52#: Applications/applications.js:68
52#: Applications/applications.js:68
53msgid "Notepad"
53msgid "Notepad"
54−msgstr ""
54+msgstr "Bloc-notes"
55
55
56#: Applications/applications.js:74
56#: Applications/applications.js:74
57msgid "Calendar"
57msgid "Calendar"
58−msgstr ""
58+msgstr "Agenda"
59
59
60#: Applications/applications.js:80
60#: Applications/applications.js:80
61msgid "Media Player"
61msgid "Media Player"
62−msgstr ""
62+msgstr "Lecteur multimédia"
63
63
64#: Applications/applications.js:86
64#: Applications/applications.js:86
65msgid "Evernote"
65msgid "Evernote"
66−msgstr ""
66+msgstr "Evernote"
67
67
68#: Applications/applications.js:91
68#: Applications/applications.js:91
69msgid "Map"
69msgid "Map"
@@ -71,27 +71,27 @@ msgstr ""
71
71
72#: Applications/applications.js:96
72#: Applications/applications.js:96
73msgid "Pinterest"
73msgid "Pinterest"
74−msgstr ""
74+msgstr "Pinterest"
75
75
76#: Applications/applications.js:101
76#: Applications/applications.js:101
77msgid "SoundCloud"
77msgid "SoundCloud"
78−msgstr ""
78+msgstr "SoundCloud"
79
79
80#: Applications/applications.js:106
80#: Applications/applications.js:106
81msgid "Wikipedia"
81msgid "Wikipedia"
82−msgstr ""
82+msgstr "Wikipédia"
83
83
84#: Applications/applications.js:111
84#: Applications/applications.js:111
85msgid "YouTube"
85msgid "YouTube"
86−msgstr ""
86+msgstr "YouTube"
87
87
88#: Components/PageHeader.qml:300
88#: Components/PageHeader.qml:300
89msgid "Recent searches"
89msgid "Recent searches"
90−msgstr ""
90+msgstr "Recherches récentes"
91
91
92#: Dash/DashApps.qml:65
92#: Dash/DashApps.qml:65
93msgid "Running apps"
93msgid "Running apps"
94−msgstr ""
94+msgstr "Applications en cours d’exécution"
95
95
96#: Dash/DashApps.qml:68
96#: Dash/DashApps.qml:68
97msgid "Frequently used"
97msgid "Frequently used"
@@ -99,7 +99,7 @@ msgstr ""
99
99
100#: Dash/DashApps.qml:71
100#: Dash/DashApps.qml:71
101msgid "Installed"
101msgid "Installed"
102−msgstr ""
102+msgstr "Installées"
103
103
104#: Dash/DashApps.qml:74
104#: Dash/DashApps.qml:74
105msgid "Available for download"
105msgid "Available for download"
@@ -109,29 +109,21 @@ msgstr ""
109msgid "Apps"
109msgid "Apps"
110msgstr "Applications"
110msgstr "Applications"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114−msgstr ""
114+msgstr "Applications fréquemment utilisées"
115−
116−#: Dash/DashHome.qml:46
117−msgid "Favourite People"
118−msgstr ""
119
115
120−#: Dash/DashHome.qml:49
116+#: Dash/DashHome.qml:43
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126−msgstr ""
118+msgstr "Musique récente"
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130−msgstr ""
122+msgstr "Vidéos populaires en ligne"
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134−msgstr ""
126+msgstr "Accueil"
135
127
136#: Dash/DashMusic.qml:27 Dash/DashVideos.qml:28
128#: Dash/DashMusic.qml:27 Dash/DashVideos.qml:28
137msgid "Featured"
129msgid "Featured"
@@ -143,7 +135,7 @@ msgstr ""
143
135
144#: Dash/DashMusic.qml:29 Dash/DashVideos.qml:30
136#: Dash/DashMusic.qml:29 Dash/DashVideos.qml:30
145msgid "New Releases"
137msgid "New Releases"
146−msgstr ""
138+msgstr "Nouveautés"
147
139
148#: Dash/DashMusic.qml:30
140#: Dash/DashMusic.qml:30
149msgid "Top Charting"
141msgid "Top Charting"
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "Musique"
146msgstr "Musique"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr ""
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -183,44 +155,44 @@ msgstr "Vidéos"
183
155
184#: Dash/Video/VideoPreview.qml:98
156#: Dash/Video/VideoPreview.qml:98
185msgid "Directed by:"
157msgid "Directed by:"
186−msgstr ""
158+msgstr "Réalisé par :"
187
159
188#: Dash/Video/VideoPreview.qml:121
160#: Dash/Video/VideoPreview.qml:121
189msgid "Starring:"
161msgid "Starring:"
190−msgstr ""
162+msgstr "Acteurs :"
191
163
192#: Dash/Video/VideoPreview.qml:144
164#: Dash/Video/VideoPreview.qml:144
193msgid "Author:"
165msgid "Author:"
194−msgstr ""
166+msgstr "Auteur :"
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
200#: Greeter/PassphraseLockscreen.qml:59
172#: Greeter/PassphraseLockscreen.qml:59
201#, qt-format
173#, qt-format
202msgid "Hello %1"
174msgid "Hello %1"
203−msgstr ""
175+msgstr "Bonjour %1"
204
176
205#: Greeter/PassphraseLockscreen.qml:59
177#: Greeter/PassphraseLockscreen.qml:59
206msgid "Hello"
178msgid "Hello"
207−msgstr ""
179+msgstr "Bonjour"
208
180
209#: Hud/HudParametrizedActionsPage.qml:132
181#: Hud/HudParametrizedActionsPage.qml:132
210msgid "Confirm"
182msgid "Confirm"
211−msgstr ""
183+msgstr "Confirmer"
212
184
213#: Hud/Hud.qml:61 Hud/Hud.qml:99 Hud/Hud.qml:372
185#: Hud/Hud.qml:61 Hud/Hud.qml:99 Hud/Hud.qml:372
214msgid "Type or say a command"
186msgid "Type or say a command"
215−msgstr ""
187+msgstr "Entrez ou dictez une commande"
216
188
217#: Hud/Hud.qml:84
189#: Hud/Hud.qml:84
218msgid "Loading. Please Wait..."
190msgid "Loading. Please Wait..."
219−msgstr ""
191+msgstr "Chargement. Veuillez patienter..."
220
192
221#: Hud/Hud.qml:89
193#: Hud/Hud.qml:89
222msgid "Speak Now..."
194msgid "Speak Now..."
223−msgstr ""
195+msgstr "Parlez maintenant..."
224
196
225#: Hud/Hud.qml:94
197#: Hud/Hud.qml:94
226msgid "Speaking..."
198msgid "Speaking..."
@@ -232,21 +204,38 @@ msgstr ""
232
204
233#: Panel/Menus/Overview/FlightModeWidget.qml:42
205#: Panel/Menus/Overview/FlightModeWidget.qml:42
234msgid "Flight mode"
206msgid "Flight mode"
235−msgstr ""
207+msgstr "Mode avion"
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239−msgstr ""
211+msgstr "Rechercher"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243−msgstr ""
215+msgstr "Désolé, aucun résultat ne correspond à votre recherche."
244−
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr ""
248
216
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "Home screen"
223+#~ msgstr "Écran d’accueil"
224+
225+#~ msgid "People"
226+#~ msgstr "Contacts"
227+
228+#~ msgid "Favourite People"
229+#~ msgstr "Contacts favoris"
230+
231+#~ msgid "People Recently in Touch"
232+#~ msgstr "Contacts récents"
233+
234+#~ msgid "A-Z"
235+#~ msgstr "A-Z"
236+
237+#~ msgid "New Contacts"
238+#~ msgstr "Nouveaux contacts"
239+
240+#~ msgid "Favourites"
241+#~ msgstr "Favoris"
po/gl.po+24−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Galician <gl@li.org>\n"
13"Language-Team: Galician <gl@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−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr "Dispoñíbel para descargar"
109msgid "Apps"
109msgid "Apps"
110msgstr "Aplicativos"
110msgstr "Aplicativos"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr "Aplicativos frecuentes"
114msgstr "Aplicativos frecuentes"
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr "Xente favorita"
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr "Xente contactada recentemente"
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr "Música recente"
118msgstr "Música recente"
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr "Vídeos populares en liña"
122msgstr "Vídeos populares en liña"
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Cartafol persoal"
126msgstr "Cartafol persoal"
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "Música"
146msgstr "Música"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "Persoas"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,27 @@ msgstr "Dispositivo"
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr "Modo de voo"
207msgstr "Modo de voo"
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Buscar"
211msgstr "Buscar"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "Sentímolo, non hai nada que coincida con esta busca."
215msgstr "Sentímolo, non hai nada que coincida con esta busca."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "Pantalla de inicio"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "People"
223+#~ msgstr "Persoas"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "Pantalla de inicio"
227+
228+#~ msgid "Favourite People"
229+#~ msgstr "Xente favorita"
230+
231+#~ msgid "People Recently in Touch"
232+#~ msgstr "Xente contactada recentemente"
po/he.po+18−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\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−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr ""
109msgid "Apps"
109msgid "Apps"
110msgstr "יישומים"
110msgstr "יישומים"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr ""
114msgstr ""
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr ""
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr ""
118msgstr ""
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr ""
122msgstr ""
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "בית"
126msgstr "בית"
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "מוזיקה"
146msgstr "מוזיקה"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "אנשים"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,21 @@ msgstr ""
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr ""
207msgstr ""
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "חיפוש"
211msgstr "חיפוש"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "שום דבר אינו תואם לחיפוש שלך, עמך הסליחה."
215msgstr "שום דבר אינו תואם לחיפוש שלך, עמך הסליחה."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "מסך הבית"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "People"
223+#~ msgstr "אנשים"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "מסך הבית"
po/hr.po+18−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Croatian <hr@li.org>\n"
13"Language-Team: Croatian <hr@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−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr ""
109msgid "Apps"
109msgid "Apps"
110msgstr "Aplikacije"
110msgstr "Aplikacije"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr ""
114msgstr ""
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr ""
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr ""
118msgstr ""
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr ""
122msgstr ""
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Početna"
126msgstr "Početna"
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "Glazba"
146msgstr "Glazba"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "Osobe"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,21 @@ msgstr ""
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr ""
207msgstr ""
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Pretraživanje"
211msgstr "Pretraživanje"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "Nažalost, ne postoji ništa što odgovara vašoj pretrazi."
215msgstr "Nažalost, ne postoji ništa što odgovara vašoj pretrazi."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "Početni zaslon"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "People"
223+#~ msgstr "Osobe"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "Početni zaslon"
po/hu.po+18−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Hungarian <hu@li.org>\n"
13"Language-Team: Hungarian <hu@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−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr ""
109msgid "Apps"
109msgid "Apps"
110msgstr "Alkalmazások"
110msgstr "Alkalmazások"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr ""
114msgstr ""
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr ""
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr ""
118msgstr ""
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr ""
122msgstr ""
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Kezdőoldal"
126msgstr "Kezdőoldal"
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "Zene"
146msgstr "Zene"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "Emberek"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,21 @@ msgstr "Eszköz"
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr ""
207msgstr ""
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Keresés"
211msgstr "Keresés"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "Elnézést, nincs találat a keresésre."
215msgstr "Elnézést, nincs találat a keresésre."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "Kezdőképernyő"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "People"
223+#~ msgstr "Emberek"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "Kezdőképernyő"
po/hy.po+24−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-07 12:42+0000\n"
11"PO-Revision-Date: 2013-06-07 12:42+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"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr "Հասանելի ծրագրեր"
109msgid "Apps"
109msgid "Apps"
110msgstr "Ծրագրեր"
110msgstr "Ծրագրեր"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr "Հաճախակի ծրագրերը"
114msgstr "Հաճախակի ծրագրերը"
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr "Ֆավորիտներ"
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr "Վերջին մարդիկ"
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr "Վերջին երգերը"
118msgstr "Վերջին երգերը"
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr "Հայտնի օնլայն վիդեոներ"
122msgstr "Հայտնի օնլայն վիդեոներ"
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Տուն"
126msgstr "Տուն"
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "Երգեր"
146msgstr "Երգեր"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "Մարդիկ"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,27 @@ msgstr "Սարք"
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr "Անկապ րեժիմ"
207msgstr "Անկապ րեժիմ"
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Որոնում"
211msgstr "Որոնում"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "Կներերք, բայց Ձեր հարցումով ոչինչ չկար"
215msgstr "Կներերք, բայց Ձեր հարցումով ոչինչ չկար"
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "Տուն"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "People Recently in Touch"
223+#~ msgstr "Վերջին մարդիկ"
224+
225+#~ msgid "Favourite People"
226+#~ msgstr "Ֆավորիտներ"
227+
228+#~ msgid "People"
229+#~ msgstr "Մարդիկ"
230+
231+#~ msgid "Home screen"
232+#~ msgstr "Տուն"
po/id.po+12−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11"PO-Revision-Date: 2013-06-05 22:20+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"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr ""
109msgid "Apps"
109msgid "Apps"
110msgstr ""
110msgstr ""
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr ""
114msgstr ""
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr ""
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr ""
118msgstr ""
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr ""
122msgstr ""
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr ""
126msgstr ""
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr ""
146msgstr ""
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr ""
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,15 @@ msgstr ""
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr ""
207msgstr ""
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr ""
211msgstr ""
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr ""
215msgstr ""
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr ""
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
po/it.po+18−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Italian <it@li.org>\n"
13"Language-Team: Italian <it@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−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr ""
109msgid "Apps"
109msgid "Apps"
110msgstr "Applicazioni"
110msgstr "Applicazioni"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr ""
114msgstr ""
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr ""
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr ""
118msgstr ""
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr ""
122msgstr ""
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Home"
126msgstr "Home"
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "Musica"
146msgstr "Musica"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "Contatti"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,21 @@ msgstr ""
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr ""
207msgstr ""
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Cerca"
211msgstr "Cerca"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "Nessun risultato corrispondente alla ricerca."
215msgstr "Nessun risultato corrispondente alla ricerca."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "Home"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "People"
223+#~ msgstr "Contatti"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "Home"
po/ja.po+12−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-15 14:12+0000\n"
11"PO-Revision-Date: 2013-06-15 14:12+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"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr ""
109msgid "Apps"
109msgid "Apps"
110msgstr ""
110msgstr ""
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr ""
114msgstr ""
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr ""
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr ""
118msgstr ""
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr ""
122msgstr ""
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr ""
126msgstr ""
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr ""
146msgstr ""
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr ""
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,15 @@ msgstr ""
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr ""
207msgstr ""
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr ""
211msgstr ""
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr ""
215msgstr ""
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr ""
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
po/kn.po+18−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Kannada <kn@li.org>\n"
13"Language-Team: Kannada <kn@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−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr ""
109msgid "Apps"
109msgid "Apps"
110msgstr "ಅಪ್ಲಿಕೇಶನ್‌ಗಳು"
110msgstr "ಅಪ್ಲಿಕೇಶನ್‌ಗಳು"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr ""
114msgstr ""
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr ""
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr ""
118msgstr ""
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr ""
122msgstr ""
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "ಮನೆ (Home)"
126msgstr "ಮನೆ (Home)"
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "ಸಂಗೀತ"
146msgstr "ಸಂಗೀತ"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "ಜನರು"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,21 @@ msgstr ""
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr ""
207msgstr ""
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "ಹುಡುಕು"
211msgstr "ಹುಡುಕು"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "ಕ್ಷಮಿಸಿ ನಿಮ್ಮ ಶೋಧನೆಗೆ ಸರಿಯಾದ ಹೊಂದಾಣಿಕೆಗಳು ದೊರಕುತ್ತಿಲ್ಲ"
215msgstr "ಕ್ಷಮಿಸಿ ನಿಮ್ಮ ಶೋಧನೆಗೆ ಸರಿಯಾದ ಹೊಂದಾಣಿಕೆಗಳು ದೊರಕುತ್ತಿಲ್ಲ"
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "ಹೋಮ್ ಸ್ಕ್ರೀನ್"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "People"
223+#~ msgstr "ಜನರು"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "ಹೋಮ್ ಸ್ಕ್ರೀನ್"
po/ko.po+12−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Korean <ko@li.org>\n"
13"Language-Team: Korean <ko@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−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr "내려받을 수 있음"
109msgid "Apps"
109msgid "Apps"
110msgstr "앱"
110msgstr "앱"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr "자주 쓰는 앱"
114msgstr "자주 쓰는 앱"
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr ""
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr "요즈음 찾는 음악"
118msgstr "요즈음 찾는 음악"
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr ""
122msgstr ""
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr ""
126msgstr ""
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "음악"
146msgstr "음악"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr ""
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,15 @@ msgstr ""
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr ""
207msgstr ""
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "찾기"
211msgstr "찾기"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr ""
215msgstr ""
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr ""
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
po/ky.po+18−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Kirghiz <ky@li.org>\n"
13"Language-Team: Kirghiz <ky@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−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr ""
109msgid "Apps"
109msgid "Apps"
110msgstr "Тиркемелер"
110msgstr "Тиркемелер"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr ""
114msgstr ""
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr ""
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr ""
118msgstr ""
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr ""
122msgstr ""
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Үй папкасы"
126msgstr "Үй папкасы"
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "Музыка"
146msgstr "Музыка"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "Адамдар"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,21 @@ msgstr ""
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr ""
207msgstr ""
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Издөө"
211msgstr "Издөө"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "Тилекке каршы, сиздин издөөңүзгө эч нерсе дал келген жок."
215msgstr "Тилекке каршы, сиздин издөөңүзгө эч нерсе дал келген жок."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "Башкы экран"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "People"
223+#~ msgstr "Адамдар"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "Башкы экран"
po/lv.po+18−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Latvian <lv@li.org>\n"
13"Language-Team: Latvian <lv@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−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr ""
109msgid "Apps"
109msgid "Apps"
110msgstr "Lietotnes"
110msgstr "Lietotnes"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr ""
114msgstr ""
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr ""
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr ""
118msgstr ""
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr ""
122msgstr ""
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Mājas"
126msgstr "Mājas"
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "Mūzika"
146msgstr "Mūzika"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "Cilvēki"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,21 @@ msgstr ""
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr ""
207msgstr ""
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Meklēt"
211msgstr "Meklēt"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "Diemžēl nekas neatbilst jūsu meklētajam."
215msgstr "Diemžēl nekas neatbilst jūsu meklētajam."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "Mājas ekrāns"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "People"
223+#~ msgstr "Cilvēki"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "Mājas ekrāns"
po/my.po+15−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Burmese <my@li.org>\n"
13"Language-Team: Burmese <my@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr ""
109msgid "Apps"
109msgid "Apps"
110msgstr "Apps"
110msgstr "Apps"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr ""
114msgstr ""
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr ""
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr ""
118msgstr ""
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr ""
122msgstr ""
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "ပင်မ"
126msgstr "ပင်မ"
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "တေးဂီတ"
146msgstr "တေးဂီတ"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "လူ"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,18 @@ msgstr ""
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr ""
207msgstr ""
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "ရှာဖွေ"
211msgstr "ရှာဖွေ"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "ဆောရီး၊ သင်၏ရှာဖွေမူနှင့်တူညီတာဘာမှမရှိပါ။"
215msgstr "ဆောရီး၊ သင်၏ရှာဖွေမူနှင့်တူညီတာဘာမှမရှိပါ။"
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr ""
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "People"
223+#~ msgstr "လူ"
po/nb.po+18−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-17 09:10+0000\n"
11"PO-Revision-Date: 2013-06-17 09:10+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"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr "Tilgjengelig for nedlasting"
109msgid "Apps"
109msgid "Apps"
110msgstr "Programmer"
110msgstr "Programmer"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr ""
114msgstr ""
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr ""
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr ""
118msgstr ""
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr ""
122msgstr ""
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Hjem"
126msgstr "Hjem"
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "Musikk"
146msgstr "Musikk"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "Personer"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,21 @@ msgstr "Enhet"
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr "Flymodus"
207msgstr "Flymodus"
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Søk"
211msgstr "Søk"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "Søket ga ingen treff."
215msgstr "Søket ga ingen treff."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "Hjemmeskjerm"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "People"
223+#~ msgstr "Personer"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "Hjemmeskjerm"
po/nl.po+18−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Dutch <nl@li.org>\n"
13"Language-Team: Dutch <nl@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−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:15+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr ""
109msgid "Apps"
109msgid "Apps"
110msgstr "Apps"
110msgstr "Apps"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr ""
114msgstr ""
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr ""
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr ""
118msgstr ""
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr ""
122msgstr ""
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Hoofdvenster"
126msgstr "Hoofdvenster"
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "Muziek"
146msgstr "Muziek"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "Mensen"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,21 @@ msgstr ""
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr ""
207msgstr ""
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Zoeken"
211msgstr "Zoeken"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "Er is helaas niets dat met uw zoekopdracht overeenkomt."
215msgstr "Er is helaas niets dat met uw zoekopdracht overeenkomt."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "Startscherm"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "People"
223+#~ msgstr "Mensen"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "Startscherm"
po/pl.po+36−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-05 22:43+0000\n"
11"PO-Revision-Date: 2013-06-05 22:43+0000\n"
12"Last-Translator: Piotr Merski <Unknown>\n"
12"Last-Translator: Piotr Merski <Unknown>\n"
13"Language-Team: Polish <pl@li.org>\n"
13"Language-Team: Polish <pl@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−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr "Dostępne do pobrania"
109msgid "Apps"
109msgid "Apps"
110msgstr "Aplikacje"
110msgstr "Aplikacje"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr "Często używane aplikacje"
114msgstr "Często używane aplikacje"
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr "Ulubione kontakty"
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr "Osoby ostatnio w kontakcie"
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr "Najnowsza muzyka"
118msgstr "Najnowsza muzyka"
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr "Wideo popularne online"
122msgstr "Wideo popularne online"
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Dom"
126msgstr "Dom"
135
127
@@ -153,26 +145,6 @@ msgstr "Przeboje"
153msgid "Music"
145msgid "Music"
154msgstr "Muzyka"
146msgstr "Muzyka"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr "Ulubione"
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr "Ostatnio w kontakcie"
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr "Nowe kontakty"
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr "A-Z"
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "Ludzie"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr "Popularne w sieci"
150msgstr "Popularne w sieci"
@@ -193,7 +165,7 @@ msgstr "Obsada:"
193msgid "Author:"
165msgid "Author:"
194msgstr "Autor:"
166msgstr "Autor:"
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,39 @@ msgstr "Urządzenie"
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr "Tryb samolotowy"
207msgstr "Tryb samolotowy"
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Szukaj"
211msgstr "Szukaj"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "Nie znaleziono pasujących wyników."
215msgstr "Nie znaleziono pasujących wyników."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "Ekran domowy"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "Home screen"
223+#~ msgstr "Ekran domowy"
224+
225+#~ msgid "People"
226+#~ msgstr "Ludzie"
227+
228+#~ msgid "People Recently in Touch"
229+#~ msgstr "Osoby ostatnio w kontakcie"
230+
231+#~ msgid "Favourite People"
232+#~ msgstr "Ulubione kontakty"
233+
234+#~ msgid "A-Z"
235+#~ msgstr "A-Z"
236+
237+#~ msgid "Recently in touch"
238+#~ msgstr "Ostatnio w kontakcie"
239+
240+#~ msgid "New Contacts"
241+#~ msgstr "Nowe kontakty"
242+
243+#~ msgid "Favourites"
244+#~ msgstr "Ulubione"
po/pt_BR.po+18−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Brazilian Portuguese <pt_BR@li.org>\n"
13"Language-Team: Brazilian Portuguese <pt_BR@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−"X-Launchpad-Export-Date: 2013-06-20 06:37+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr ""
109msgid "Apps"
109msgid "Apps"
110msgstr "Aplicativos"
110msgstr "Aplicativos"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr ""
114msgstr ""
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr ""
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr ""
118msgstr ""
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr ""
122msgstr ""
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Início"
126msgstr "Início"
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "Músicas"
146msgstr "Músicas"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "Pessoas"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,21 @@ msgstr ""
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr ""
207msgstr ""
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Pesquisar"
211msgstr "Pesquisar"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "Desculpe, não há nada que corresponda à sua pesquisa."
215msgstr "Desculpe, não há nada que corresponda à sua pesquisa."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "Tela inicial"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "People"
223+#~ msgstr "Pessoas"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "Tela inicial"
po/ro.po+18−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Romanian <ro@li.org>\n"
13"Language-Team: Romanian <ro@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−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr ""
109msgid "Apps"
109msgid "Apps"
110msgstr "Aplicații"
110msgstr "Aplicații"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr ""
114msgstr ""
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr ""
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr ""
118msgstr ""
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr ""
122msgstr ""
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Acasă"
126msgstr "Acasă"
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "Muzică"
146msgstr "Muzică"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "Persoane"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,20 +206,22 @@ msgstr ""
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr ""
207msgstr ""
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Căutare"
211msgstr "Căutare"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr ""
215msgstr ""
244"Ne pare rău, nu este nimic care se potrivește căutării dumneavoastră."
216"Ne pare rău, nu este nimic care se potrivește căutării dumneavoastră."
245
217
246−#: plugins/Unity/lenses.cpp:39
247−msgid "Home screen"
248−msgstr "Ecran principal"
249−
250−#: Shell.qml:380
218+#: Shell.qml:383
251#, qt-format
219#, qt-format
252−msgid "Please enter %1:"
220+msgid "Please enter %1"
253msgstr ""
221msgstr ""
222+
223+#~ msgid "People"
224+#~ msgstr "Persoane"
225+
226+#~ msgid "Home screen"
227+#~ msgstr "Ecran principal"
po/ru.po+27−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-21 10:08+0000\n"
11"PO-Revision-Date: 2013-06-21 10:08+0000\n"
12"Last-Translator: Andrey Dedikov <iamawesome.ndr@gmail.com>\n"
12"Last-Translator: Andrey Dedikov <iamawesome.ndr@gmail.com>\n"
13"Language-Team: Russian <ru@li.org>\n"
13"Language-Team: Russian <ru@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−"X-Launchpad-Export-Date: 2013-06-22 06:26+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16677)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr "Доступно для загрузки"
109msgid "Apps"
109msgid "Apps"
110msgstr "Приложения"
110msgstr "Приложения"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr "Часто используемые приложения"
114msgstr "Часто используемые приложения"
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr "Избранные контакты"
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr "Недавние контакты"
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr "Недавно прослушанная музыка"
118msgstr "Недавно прослушанная музыка"
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr "Популярные видео из сети"
122msgstr "Популярные видео из сети"
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Главная"
126msgstr "Главная"
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "Музыка"
146msgstr "Музыка"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr "Новые контакты"
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "Люди"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr "В главных ролях"
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,30 @@ msgstr "Устройство"
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr "Режим полета"
207msgstr "Режим полета"
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Поиск"
211msgstr "Поиск"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "Извините, поиск не дал результатов."
215msgstr "Извините, поиск не дал результатов."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "Главный экран"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "People"
223+#~ msgstr "Люди"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "Главный экран"
227+
228+#~ msgid "Favourite People"
229+#~ msgstr "Избранные контакты"
230+
231+#~ msgid "People Recently in Touch"
232+#~ msgstr "Недавние контакты"
233+
234+#~ msgid "New Contacts"
235+#~ msgstr "Новые контакты"
po/si.po+12−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11"PO-Revision-Date: 2013-06-05 22:20+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"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr ""
109msgid "Apps"
109msgid "Apps"
110msgstr ""
110msgstr ""
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr ""
114msgstr ""
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr ""
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr ""
118msgstr ""
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr ""
122msgstr ""
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr ""
126msgstr ""
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr ""
146msgstr ""
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr ""
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,15 @@ msgstr ""
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr ""
207msgstr ""
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr ""
211msgstr ""
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr ""
215msgstr ""
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr ""
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
po/sl.po+43−69
@@ -7,83 +7,83 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-09 10:23+0000\n"
11+"PO-Revision-Date: 2013-06-29 10:26+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"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-20 06:37+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-30 07:12+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16692)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
22−msgstr ""
22+msgstr "Telefon"
23
23
24#: Applications/applications.js:29
24#: Applications/applications.js:29
25msgid "Camera"
25msgid "Camera"
26−msgstr ""
26+msgstr "Fotoaparat"
27
27
28#: Applications/applications.js:35
28#: Applications/applications.js:35
29msgid "Gallery"
29msgid "Gallery"
30−msgstr ""
30+msgstr "Galerija"
31
31
32#: Applications/applications.js:40
32#: Applications/applications.js:40
33msgid "Facebook"
33msgid "Facebook"
34−msgstr ""
34+msgstr "Facebook"
35
35
36#: Applications/applications.js:46
36#: Applications/applications.js:46
37msgid "Browser"
37msgid "Browser"
38−msgstr ""
38+msgstr "Brskalnik"
39
39
40#: Applications/applications.js:51
40#: Applications/applications.js:51
41msgid "Twitter"
41msgid "Twitter"
42−msgstr ""
42+msgstr "Twitter"
43
43
44#: Applications/applications.js:57
44#: Applications/applications.js:57
45msgid "GMail"
45msgid "GMail"
46−msgstr ""
46+msgstr "GMail"
47
47
48#: Applications/applications.js:62
48#: Applications/applications.js:62
49msgid "Weather"
49msgid "Weather"
50−msgstr ""
50+msgstr "Vreme"
51
51
52#: Applications/applications.js:68
52#: Applications/applications.js:68
53msgid "Notepad"
53msgid "Notepad"
54−msgstr ""
54+msgstr "Beležnica"
55
55
56#: Applications/applications.js:74
56#: Applications/applications.js:74
57msgid "Calendar"
57msgid "Calendar"
58−msgstr ""
58+msgstr "Koledar"
59
59
60#: Applications/applications.js:80
60#: Applications/applications.js:80
61msgid "Media Player"
61msgid "Media Player"
62−msgstr ""
62+msgstr "Predvajalnik predstavnosti"
63
63
64#: Applications/applications.js:86
64#: Applications/applications.js:86
65msgid "Evernote"
65msgid "Evernote"
66−msgstr ""
66+msgstr "Evernote"
67
67
68#: Applications/applications.js:91
68#: Applications/applications.js:91
69msgid "Map"
69msgid "Map"
70−msgstr ""
70+msgstr "Zemljevid"
71
71
72#: Applications/applications.js:96
72#: Applications/applications.js:96
73msgid "Pinterest"
73msgid "Pinterest"
74−msgstr ""
74+msgstr "Pinterest"
75
75
76#: Applications/applications.js:101
76#: Applications/applications.js:101
77msgid "SoundCloud"
77msgid "SoundCloud"
78−msgstr ""
78+msgstr "SoundCloud"
79
79
80#: Applications/applications.js:106
80#: Applications/applications.js:106
81msgid "Wikipedia"
81msgid "Wikipedia"
82−msgstr ""
82+msgstr "Wikipedija"
83
83
84#: Applications/applications.js:111
84#: Applications/applications.js:111
85msgid "YouTube"
85msgid "YouTube"
86−msgstr ""
86+msgstr "YouTube"
87
87
88#: Components/PageHeader.qml:300
88#: Components/PageHeader.qml:300
89msgid "Recent searches"
89msgid "Recent searches"
@@ -109,27 +109,19 @@ msgstr "Na voljo za prejem"
109msgid "Apps"
109msgid "Apps"
110msgstr "Programi"
110msgstr "Programi"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr ""
114msgstr ""
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr ""
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr "Nedavna glasba"
118msgstr "Nedavna glasba"
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr ""
122msgstr ""
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Domov"
126msgstr "Domov"
135
127
@@ -139,11 +131,11 @@ msgstr ""
139
131
140#: Dash/DashMusic.qml:28 Dash/DashVideos.qml:29
132#: Dash/DashMusic.qml:28 Dash/DashVideos.qml:29
141msgid "Recent"
133msgid "Recent"
142−msgstr ""
134+msgstr "Nedavno"
143
135
144#: Dash/DashMusic.qml:29 Dash/DashVideos.qml:30
136#: Dash/DashMusic.qml:29 Dash/DashVideos.qml:30
145msgid "New Releases"
137msgid "New Releases"
146−msgstr ""
138+msgstr "Nove izdaje"
147
139
148#: Dash/DashMusic.qml:30
140#: Dash/DashMusic.qml:30
149msgid "Top Charting"
141msgid "Top Charting"
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "Glasba"
146msgstr "Glasba"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "Ljudje"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -191,20 +163,20 @@ msgstr ""
191
163
192#: Dash/Video/VideoPreview.qml:144
164#: Dash/Video/VideoPreview.qml:144
193msgid "Author:"
165msgid "Author:"
194−msgstr ""
166+msgstr "Avtor:"
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198−msgstr ""
170+msgstr "Klic v sili"
199
171
200#: Greeter/PassphraseLockscreen.qml:59
172#: Greeter/PassphraseLockscreen.qml:59
201#, qt-format
173#, qt-format
202msgid "Hello %1"
174msgid "Hello %1"
203−msgstr ""
175+msgstr "Pozdravljeni, %1"
204
176
205#: Greeter/PassphraseLockscreen.qml:59
177#: Greeter/PassphraseLockscreen.qml:59
206msgid "Hello"
178msgid "Hello"
207−msgstr ""
179+msgstr "Pozdravljeni"
208
180
209#: Hud/HudParametrizedActionsPage.qml:132
181#: Hud/HudParametrizedActionsPage.qml:132
210msgid "Confirm"
182msgid "Confirm"
@@ -234,19 +206,21 @@ msgstr "Naprava"
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr "Način letenja"
207msgstr "Način letenja"
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Iskanje"
211msgstr "Iskanje"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "Nič se ne ujema z vašim iskalnim nizom."
215msgstr "Nič se ne ujema z vašim iskalnim nizom."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "Domači zaslon"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252−msgstr ""
220+msgstr "Vnesite %1"
221+
222+#~ msgid "People"
223+#~ msgstr "Ljudje"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "Domači zaslon"
po/sr.po+18−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Serbian <sr@li.org>\n"
13"Language-Team: Serbian <sr@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−"X-Launchpad-Export-Date: 2013-06-20 06:36+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr ""
109msgid "Apps"
109msgid "Apps"
110msgstr "Програми"
110msgstr "Програми"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr ""
114msgstr ""
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr ""
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr ""
118msgstr ""
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr ""
122msgstr ""
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Почетна"
126msgstr "Почетна"
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "Музика"
146msgstr "Музика"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "Људи"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,21 @@ msgstr ""
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr ""
207msgstr ""
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Претрага"
211msgstr "Претрага"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "Нажалост, претрага није наишла на икакво подударање."
215msgstr "Нажалост, претрага није наишла на икакво подударање."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "Почетни екран"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "People"
223+#~ msgstr "Људи"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "Почетни екран"
po/sv.po+12−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11"PO-Revision-Date: 2013-06-05 22:20+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"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-20 06:37+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr ""
109msgid "Apps"
109msgid "Apps"
110msgstr ""
110msgstr ""
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr ""
114msgstr ""
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr ""
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr ""
118msgstr ""
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr ""
122msgstr ""
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr ""
126msgstr ""
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr ""
146msgstr ""
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr ""
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,15 @@ msgstr ""
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr ""
207msgstr ""
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr ""
211msgstr ""
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr ""
215msgstr ""
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr ""
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
po/te.po+12−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Telugu <te@li.org>\n"
13"Language-Team: Telugu <te@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−"X-Launchpad-Export-Date: 2013-06-20 06:37+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr ""
109msgid "Apps"
109msgid "Apps"
110msgstr ""
110msgstr ""
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr ""
114msgstr ""
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr ""
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr ""
118msgstr ""
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr ""
122msgstr ""
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "నివాసం"
126msgstr "నివాసం"
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "సంగీతం"
146msgstr "సంగీతం"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr ""
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,15 @@ msgstr ""
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr ""
207msgstr ""
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr ""
211msgstr ""
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr ""
215msgstr ""
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr ""
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
po/th.ponew file+220
@@ -0,0 +1,220 @@
1+# Thai translation for unity
2+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
3+# This file is distributed under the same license as the unity package.
4+# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
5+#
6+msgid ""
7+msgstr ""
8+"Project-Id-Version: unity\n"
9+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11+"PO-Revision-Date: 2013-06-28 15:34+0000\n"
12+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13+"Language-Team: Thai <th@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+"X-Launchpad-Export-Date: 2013-06-30 07:12+0000\n"
18+"X-Generator: Launchpad (build 16692)\n"
19+
20+#: Applications/applications.js:23
21+msgid "Phone"
22+msgstr ""
23+
24+#: Applications/applications.js:29
25+msgid "Camera"
26+msgstr ""
27+
28+#: Applications/applications.js:35
29+msgid "Gallery"
30+msgstr ""
31+
32+#: Applications/applications.js:40
33+msgid "Facebook"
34+msgstr ""
35+
36+#: Applications/applications.js:46
37+msgid "Browser"
38+msgstr ""
39+
40+#: Applications/applications.js:51
41+msgid "Twitter"
42+msgstr ""
43+
44+#: Applications/applications.js:57
45+msgid "GMail"
46+msgstr ""
47+
48+#: Applications/applications.js:62
49+msgid "Weather"
50+msgstr ""
51+
52+#: Applications/applications.js:68
53+msgid "Notepad"
54+msgstr ""
55+
56+#: Applications/applications.js:74
57+msgid "Calendar"
58+msgstr ""
59+
60+#: Applications/applications.js:80
61+msgid "Media Player"
62+msgstr ""
63+
64+#: Applications/applications.js:86
65+msgid "Evernote"
66+msgstr ""
67+
68+#: Applications/applications.js:91
69+msgid "Map"
70+msgstr ""
71+
72+#: Applications/applications.js:96
73+msgid "Pinterest"
74+msgstr ""
75+
76+#: Applications/applications.js:101
77+msgid "SoundCloud"
78+msgstr ""
79+
80+#: Applications/applications.js:106
81+msgid "Wikipedia"
82+msgstr ""
83+
84+#: Applications/applications.js:111
85+msgid "YouTube"
86+msgstr ""
87+
88+#: Components/PageHeader.qml:300
89+msgid "Recent searches"
90+msgstr ""
91+
92+#: Dash/DashApps.qml:65
93+msgid "Running apps"
94+msgstr ""
95+
96+#: Dash/DashApps.qml:68
97+msgid "Frequently used"
98+msgstr ""
99+
100+#: Dash/DashApps.qml:71
101+msgid "Installed"
102+msgstr ""
103+
104+#: Dash/DashApps.qml:74
105+msgid "Available for download"
106+msgstr ""
107+
108+#: Dash/DashApps.qml:178
109+msgid "Apps"
110+msgstr ""
111+
112+#: Dash/DashHome.qml:40
113+msgid "Frequent Apps"
114+msgstr ""
115+
116+#: Dash/DashHome.qml:43
117+msgid "Recent Music"
118+msgstr ""
119+
120+#: Dash/DashHome.qml:46
121+msgid "Videos Popular Online"
122+msgstr ""
123+
124+#: Dash/DashHome.qml:175
125+msgid "Home"
126+msgstr ""
127+
128+#: Dash/DashMusic.qml:27 Dash/DashVideos.qml:28
129+msgid "Featured"
130+msgstr ""
131+
132+#: Dash/DashMusic.qml:28 Dash/DashVideos.qml:29
133+msgid "Recent"
134+msgstr ""
135+
136+#: Dash/DashMusic.qml:29 Dash/DashVideos.qml:30
137+msgid "New Releases"
138+msgstr ""
139+
140+#: Dash/DashMusic.qml:30
141+msgid "Top Charting"
142+msgstr ""
143+
144+#: Dash/DashMusic.qml:99
145+msgid "Music"
146+msgstr ""
147+
148+#: Dash/DashVideos.qml:31
149+msgid "Popular Online"
150+msgstr ""
151+
152+#: Dash/DashVideos.qml:155
153+msgid "Videos"
154+msgstr ""
155+
156+#: Dash/Video/VideoPreview.qml:98
157+msgid "Directed by:"
158+msgstr ""
159+
160+#: Dash/Video/VideoPreview.qml:121
161+msgid "Starring:"
162+msgstr ""
163+
164+#: Dash/Video/VideoPreview.qml:144
165+msgid "Author:"
166+msgstr ""
167+
168+#: Greeter/Lockscreen.qml:133
169+msgid "Emergency call"
170+msgstr ""
171+
172+#: Greeter/PassphraseLockscreen.qml:59
173+#, qt-format
174+msgid "Hello %1"
175+msgstr ""
176+
177+#: Greeter/PassphraseLockscreen.qml:59
178+msgid "Hello"
179+msgstr ""
180+
181+#: Hud/HudParametrizedActionsPage.qml:132
182+msgid "Confirm"
183+msgstr ""
184+
185+#: Hud/Hud.qml:61 Hud/Hud.qml:99 Hud/Hud.qml:372
186+msgid "Type or say a command"
187+msgstr ""
188+
189+#: Hud/Hud.qml:84
190+msgid "Loading. Please Wait..."
191+msgstr ""
192+
193+#: Hud/Hud.qml:89
194+msgid "Speak Now..."
195+msgstr ""
196+
197+#: Hud/Hud.qml:94
198+msgid "Speaking..."
199+msgstr ""
200+
201+#: Panel/MenuContent.qml:192
202+msgid "Device"
203+msgstr ""
204+
205+#: Panel/Menus/Overview/FlightModeWidget.qml:42
206+msgid "Flight mode"
207+msgstr ""
208+
209+#: Panel/SearchIndicator.qml:26
210+msgid "Search"
211+msgstr ""
212+
213+#: plugins/Unity/scope.cpp:268
214+msgid "Sorry, there is nothing that matches your search."
215+msgstr ""
216+
217+#: Shell.qml:383
218+#, qt-format
219+msgid "Please enter %1"
220+msgstr ""
po/tr.po+33−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-24 17:24+0000\n"
11"PO-Revision-Date: 2013-06-24 17:24+0000\n"
12"Last-Translator: Adar Cem EREN <adarcemeren34@gmail.com>\n"
12"Last-Translator: Adar Cem EREN <adarcemeren34@gmail.com>\n"
13"Language-Team: Turkish <tr@li.org>\n"
13"Language-Team: Turkish <tr@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-25 06:00+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16677)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr "İndirilebilir durumda"
109msgid "Apps"
109msgid "Apps"
110msgstr "Uygulamalar"
110msgstr "Uygulamalar"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr "Sıkça Kullanılan Uygulamalar"
114msgstr "Sıkça Kullanılan Uygulamalar"
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr "Favori Kişiler"
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr "En Son Konuşulan Kişiler"
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr "En Son Müzik"
118msgstr "En Son Müzik"
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr "Çevrimiçi Yaygın Videolar"
122msgstr "Çevrimiçi Yaygın Videolar"
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Ana Sayfa"
126msgstr "Ana Sayfa"
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "Müzik"
146msgstr "Müzik"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr "Favoriler"
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr "Yeni Kişiler"
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr "A-Z"
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "Kişiler"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr "Genellikle Çevrimiçi"
150msgstr "Genellikle Çevrimiçi"
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr "Yazar:"
166msgstr "Yazar:"
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr "Acil Arama"
170msgstr "Acil Arama"
199
171
@@ -234,19 +206,36 @@ msgstr "Aygıt"
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr "Uçak Modu"
207msgstr "Uçak Modu"
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Ara"
211msgstr "Ara"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "Üzgünüz, aramanızla eşleşen hiçbir şey yok."
215msgstr "Üzgünüz, aramanızla eşleşen hiçbir şey yok."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "Başlangıç ekranı"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "People"
223+#~ msgstr "Kişiler"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "Başlangıç ekranı"
227+
228+#~ msgid "Favourite People"
229+#~ msgstr "Favori Kişiler"
230+
231+#~ msgid "People Recently in Touch"
232+#~ msgstr "En Son Konuşulan Kişiler"
233+
234+#~ msgid "A-Z"
235+#~ msgstr "A-Z"
236+
237+#~ msgid "New Contacts"
238+#~ msgstr "Yeni Kişiler"
239+
240+#~ msgid "Favourites"
241+#~ msgstr "Favoriler"
po/ug.po+36−47
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-25 08:02+0000\n"
11+"PO-Revision-Date: 2013-06-28 04:36+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"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-26 06:20+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-30 07:12+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16692)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr "چۈشۈرگىلى بولىدىغانلىرى"
109msgid "Apps"
109msgid "Apps"
110msgstr "ئەپلەر"
110msgstr "ئەپلەر"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr "دائىم ئىشلىتىلىدىغان ئەپلەر"
114msgstr "دائىم ئىشلىتىلىدىغان ئەپلەر"
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr "ھەمىشە ئالاقە قىلىدىغان كىشىلەر"
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr "يېقىندا ئالاقە قىلغان كىشىلەر"
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr "يېقىندا ئاڭلىغان مۇزىكىلار"
118msgstr "يېقىندا ئاڭلىغان مۇزىكىلار"
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr "توردىكى ئالقىشقا ئېرىشكەن سىنلار"
122msgstr "توردىكى ئالقىشقا ئېرىشكەن سىنلار"
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "ماكان"
126msgstr "ماكان"
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "مۇزىكا"
146msgstr "مۇزىكا"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr "يېقىندا ئالاقە قىلغانلار"
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr "يېڭى ئالاقەداشلار"
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr "A-Z"
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "كىشىلەر"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,14 +165,14 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr "ئاپتور:"
166msgstr "ئاپتور:"
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr "جىددىي تېلېفون"
170msgstr "جىددىي تېلېفون"
199
171
200#: Greeter/PassphraseLockscreen.qml:59
172#: Greeter/PassphraseLockscreen.qml:59
201#, qt-format
173#, qt-format
202msgid "Hello %1"
174msgid "Hello %1"
203−msgstr ""
175+msgstr "سالام %1"
204
176
205#: Greeter/PassphraseLockscreen.qml:59
177#: Greeter/PassphraseLockscreen.qml:59
206msgid "Hello"
178msgid "Hello"
@@ -234,19 +206,36 @@ msgstr "ئۈسكۈنە"
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr "ئايروپىلاندا"
207msgstr "ئايروپىلاندا"
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "ئىزدە"
211msgstr "ئىزدە"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "كەچۈرۈڭ، ئىزدىگىنىڭىزگە ماس نەتىجە تېپىلمىدى."
215msgstr "كەچۈرۈڭ، ئىزدىگىنىڭىزگە ماس نەتىجە تېپىلمىدى."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "ماكان ئېكران"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252−msgstr "%1 نى كىرگۈزۈڭ:"
220+msgstr "%1 نى كىرگۈزۈڭ"
221+
222+#~ msgid "Favourite People"
223+#~ msgstr "ھەمىشە ئالاقە قىلىدىغان كىشىلەر"
224+
225+#~ msgid "People Recently in Touch"
226+#~ msgstr "يېقىندا ئالاقە قىلغان كىشىلەر"
227+
228+#~ msgid "People"
229+#~ msgstr "كىشىلەر"
230+
231+#~ msgid "Home screen"
232+#~ msgstr "ماكان ئېكران"
233+
234+#~ msgid "A-Z"
235+#~ msgstr "A-Z"
236+
237+#~ msgid "Recently in touch"
238+#~ msgstr "يېقىندا ئالاقە قىلغانلار"
239+
240+#~ msgid "New Contacts"
241+#~ msgstr "يېڭى ئالاقەداشلار"
po/uk.po+39−47
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-25 08:08+0000\n"
11+"PO-Revision-Date: 2013-06-29 14:27+0000\n"
12−"Last-Translator: Yuri Chornoivan <yurchor@gmail.com>\n"
12+"Last-Translator: Roman Koshkin <mar2008m@rambler.ru>\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−"X-Launchpad-Export-Date: 2013-06-26 06:20+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-30 07:12+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16692)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr "Доступно до завантаження"
109msgid "Apps"
109msgid "Apps"
110msgstr "Програми"
110msgstr "Програми"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr "Часто використовувані програми"
114msgstr "Часто використовувані програми"
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr "Вибрані контакти"
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr "Недавні контакти"
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr "Нещодавно прослухана музика"
118msgstr "Нещодавно прослухана музика"
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr "Популярні в мережі відео"
122msgstr "Популярні в мережі відео"
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "Домівка"
126msgstr "Домівка"
135
127
@@ -153,26 +145,6 @@ msgstr "З високими оцінками"
153msgid "Music"
145msgid "Music"
154msgstr "Музика"
146msgstr "Музика"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr "Улюблене"
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr "Нещодавні контакти"
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr "Нові контакти"
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr "А-Я"
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "Люди"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr "Популярне у мережі"
150msgstr "Популярне у мережі"
@@ -193,7 +165,7 @@ msgstr "Актори:"
193msgid "Author:"
165msgid "Author:"
194msgstr "Автор:"
166msgstr "Автор:"
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr "Екстрений виклик"
170msgstr "Екстрений виклик"
199
171
@@ -234,19 +206,39 @@ msgstr "Пристрій"
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr "Автономний режим"
207msgstr "Автономний режим"
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "Пошук"
211msgstr "Пошук"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "Вибачте, для вказаних вами ключових слів нічого не знайдено."
215msgstr "Вибачте, для вказаних вами ключових слів нічого не знайдено."
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "Екран домівки"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252−msgstr "Будь ласка, введіть %1:"
220+msgstr "Будь ласка, введіть %1"
221+
222+#~ msgid "People"
223+#~ msgstr "Люди"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "Екран домівки"
227+
228+#~ msgid "Favourite People"
229+#~ msgstr "Вибрані контакти"
230+
231+#~ msgid "People Recently in Touch"
232+#~ msgstr "Недавні контакти"
233+
234+#~ msgid "A-Z"
235+#~ msgstr "А-Я"
236+
237+#~ msgid "New Contacts"
238+#~ msgstr "Нові контакти"
239+
240+#~ msgid "Favourites"
241+#~ msgstr "Улюблене"
242+
243+#~ msgid "Recently in touch"
244+#~ msgstr "Нещодавні контакти"
po/unity8.pot+4−9
@@ -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-06-19 17:06+0200\n"
11+"POT-Creation-Date: 2013-06-26 22:58+0200\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"
@@ -165,7 +165,7 @@ msgstr ""
165msgid "Author:"
165msgid "Author:"
166msgstr ""
166msgstr ""
167
167
168−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
169msgid "Emergency call"
169msgid "Emergency call"
170msgstr ""
170msgstr ""
171
171
@@ -214,12 +214,7 @@ msgstr ""
214msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
215msgstr ""
215msgstr ""
216
216
217−#: Shell.qml:380
217+#: Shell.qml:383
218#, qt-format
218#, qt-format
219−msgid "Please enter %1:"
219+msgid "Please enter %1"
220−msgstr ""
221−
222−#: Shell.qml:380
223−#, qt-format
224−msgid "Please enter %1:"
225msgstr ""
220msgstr ""
po/zh_CN.po+37−45
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-22 21:20+0000\n"
11"PO-Revision-Date: 2013-06-22 21:20+0000\n"
12"Last-Translator: Anthony Wong <anthony.wong@canonical.com>\n"
12"Last-Translator: Anthony Wong <anthony.wong@canonical.com>\n"
13"Language-Team: Chinese (Simplified) <zh_CN@li.org>\n"
13"Language-Team: Chinese (Simplified) <zh_CN@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−"X-Launchpad-Export-Date: 2013-06-23 05:56+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16677)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr "可供下载"
109msgid "Apps"
109msgid "Apps"
110msgstr "应用程序"
110msgstr "应用程序"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr "常用软件"
114msgstr "常用软件"
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr "常用联系人"
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr "近期联系人"
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr "近期听过的音乐"
118msgstr "近期听过的音乐"
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr "热门在线视频"
122msgstr "热门在线视频"
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "主页"
126msgstr "主页"
135
127
@@ -153,26 +145,6 @@ msgstr "排行榜图"
153msgid "Music"
145msgid "Music"
154msgstr "音乐"
146msgstr "音乐"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr "最爱"
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr "最近联系"
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr "新建联系人"
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr "A-Z"
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "联系人"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr "经常在线"
150msgstr "经常在线"
@@ -193,7 +165,7 @@ msgstr "主演:"
193msgid "Author:"
165msgid "Author:"
194msgstr "作者:"
166msgstr "作者:"
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr "紧急呼救"
170msgstr "紧急呼救"
199
171
@@ -234,19 +206,39 @@ msgstr "设备"
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr "飞行模式"
207msgstr "飞行模式"
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "搜索"
211msgstr "搜索"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "对不起,没有找到您想要的结果。"
215msgstr "对不起,没有找到您想要的结果。"
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "主页"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252−msgstr "请输入 %1:"
220+msgstr ""
221+
222+#~ msgid "Home screen"
223+#~ msgstr "主页"
224+
225+#~ msgid "Favourite People"
226+#~ msgstr "常用联系人"
227+
228+#~ msgid "People Recently in Touch"
229+#~ msgstr "近期联系人"
230+
231+#~ msgid "People"
232+#~ msgstr "联系人"
233+
234+#~ msgid "Recently in touch"
235+#~ msgstr "最近联系"
236+
237+#~ msgid "New Contacts"
238+#~ msgstr "新建联系人"
239+
240+#~ msgid "Favourites"
241+#~ msgstr "最爱"
242+
243+#~ msgid "A-Z"
244+#~ msgstr "A-Z"
po/zh_TW.po+24−44
@@ -7,15 +7,15 @@ 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-06-19 17:06+0200\n"
10+"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
11"PO-Revision-Date: 2013-06-05 22:20+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Chinese (Traditional) <zh_TW@li.org>\n"
13"Language-Team: Chinese (Traditional) <zh_TW@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−"X-Launchpad-Export-Date: 2013-06-20 06:37+0000\n"
17+"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
18−"X-Generator: Launchpad (build 16673)\n"
18+"X-Generator: Launchpad (build 16681)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -109,27 +109,19 @@ msgstr "可供下載"
109msgid "Apps"
109msgid "Apps"
110msgstr "程式"
110msgstr "程式"
111
111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113msgid "Frequent Apps"
113msgid "Frequent Apps"
114msgstr "常用的程式"
114msgstr "常用的程式"
115
115
116−#: Dash/DashHome.qml:46
116+#: Dash/DashHome.qml:43
117−msgid "Favourite People"
118−msgstr "喜歡的朋友"
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr "最近接觸的朋友"
123−
124−#: Dash/DashHome.qml:52
125msgid "Recent Music"
117msgid "Recent Music"
126msgstr "最近聽過的音樂"
118msgstr "最近聽過的音樂"
127
119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129msgid "Videos Popular Online"
121msgid "Videos Popular Online"
130msgstr "線上熱門的影片"
122msgstr "線上熱門的影片"
131
123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133msgid "Home"
125msgid "Home"
134msgstr "家屋"
126msgstr "家屋"
135
127
@@ -153,26 +145,6 @@ msgstr ""
153msgid "Music"
145msgid "Music"
154msgstr "音樂"
146msgstr "音樂"
155
147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr "朋友"
175−
176#: Dash/DashVideos.qml:31
148#: Dash/DashVideos.qml:31
177msgid "Popular Online"
149msgid "Popular Online"
178msgstr ""
150msgstr ""
@@ -193,7 +165,7 @@ msgstr ""
193msgid "Author:"
165msgid "Author:"
194msgstr ""
166msgstr ""
195
167
196−#: Greeter/Lockscreen.qml:126
168+#: Greeter/Lockscreen.qml:133
197msgid "Emergency call"
169msgid "Emergency call"
198msgstr ""
170msgstr ""
199
171
@@ -234,19 +206,27 @@ msgstr "裝置"
234msgid "Flight mode"
206msgid "Flight mode"
235msgstr "飛航模式"
207msgstr "飛航模式"
236
208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238msgid "Search"
210msgid "Search"
239msgstr "搜尋"
211msgstr "搜尋"
240
212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242msgid "Sorry, there is nothing that matches your search."
214msgid "Sorry, there is nothing that matches your search."
243msgstr "很抱歉,找不到符合您想搜尋的結果。"
215msgstr "很抱歉,找不到符合您想搜尋的結果。"
244
216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
247−msgstr "家屋畫面"
248−
249−#: Shell.qml:380
217+#: Shell.qml:383
250#, qt-format
218#, qt-format
251−msgid "Please enter %1:"
219+msgid "Please enter %1"
252msgstr ""
220msgstr ""
221+
222+#~ msgid "People"
223+#~ msgstr "朋友"
224+
225+#~ msgid "Home screen"
226+#~ msgstr "家屋畫面"
227+
228+#~ msgid "Favourite People"
229+#~ msgstr "喜歡的朋友"
230+
231+#~ msgid "People Recently in Touch"
232+#~ msgstr "最近接觸的朋友"
run_on_device+1−1
@@ -75,7 +75,7 @@ install_dependencies() {
75sync_code() {
75sync_code() {
76 [ -e .bzr ] && bzr export --uncommitted --format=dir /tmp/$CODE_DIR
76 [ -e .bzr ] && bzr export --uncommitted --format=dir /tmp/$CODE_DIR
77 [ -e .git ] && git checkout-index -a -f --prefix=/tmp/$CODE_DIR/
77 [ -e .git ] && git checkout-index -a -f --prefix=/tmp/$CODE_DIR/
78− rsync -crlOzv -e "ssh -p $TARGET_SSH_PORT -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" /tmp/$CODE_DIR/ $USER@$TARGET_IP:$CODE_DIR/
78+ rsync -crlOzv --delete --exclude builddir -e "ssh -p $TARGET_SSH_PORT -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" /tmp/$CODE_DIR/ $USER@$TARGET_IP:$CODE_DIR/
79 rm -rf /tmp/$CODE_DIR
79 rm -rf /tmp/$CODE_DIR
80}
80}
81
81
tests/plugins/CMakeLists.txt+1
@@ -1,2 +1,3 @@
1add_subdirectory(Utils)
1add_subdirectory(Utils)
2add_subdirectory(Ubuntu)
2add_subdirectory(Ubuntu)
3+add_subdirectory(ListViewWithPageHeader)
tests/plugins/ListViewWithPageHeader/CMakeLists.txtnew file+31
@@ -0,0 +1,31 @@
1+# There's no cmake var for v8 include path :-/
2+# so create one
3+LIST(GET Qt5Core_INCLUDE_DIRS 0 QtCoreDir0)
4+SET(Qt5V8_PRIVATE_INCLUDE_DIR ${QtCoreDir0}/../QtV8/${Qt5Core_VERSION_STRING}/QtV8)
5+
6+include_directories(
7+ ${Qt5Qml_PRIVATE_INCLUDE_DIRS}
8+ ${Qt5Quick_INCLUDE_DIRS}
9+ ${Qt5Quick_PRIVATE_INCLUDE_DIRS}
10+ ${Qt5V8_PRIVATE_INCLUDE_DIR}
11+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/ListViewWithPageHeader
12+ ${CMAKE_CURRENT_BINARY_DIR}
13+ )
14+
15+remove_definitions(-DQT_NO_KEYWORDS)
16+
17+add_definitions(-DLISTVIEWWITHPAGEHEADER_FOLDER="${CMAKE_CURRENT_SOURCE_DIR}")
18+add_definitions(-DBUILT_PLUGINS_DIR="${CMAKE_BINARY_DIR}/plugins")
19+
20+add_executable(listviewwithpageheadertestExec listviewwithpageheadertest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/ListViewWithPageHeader/listviewwithpageheader.cpp)
21+qt5_use_modules(listviewwithpageheadertestExec Test Core Qml)
22+target_link_libraries(listviewwithpageheadertestExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
23+add_custom_target(testlistviewwithpageheader ${CMAKE_CURRENT_BINARY_DIR}/listviewwithpageheadertestExec -o ${CMAKE_BINARY_DIR}/testlistviewwithpageheader.xml,xunitxml -o -,txt)
24+
25+add_executable(listviewwithpageheadertestsectionExec listviewwithpageheadertestsection.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/ListViewWithPageHeader/listviewwithpageheader.cpp)
26+qt5_use_modules(listviewwithpageheadertestsectionExec Test Core Qml)
27+target_link_libraries(listviewwithpageheadertestsectionExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
28+add_custom_target(testlistviewwithpageheadersection ${CMAKE_CURRENT_BINARY_DIR}/listviewwithpageheadertestsectionExec -o ${CMAKE_BINARY_DIR}/testlistviewwithpageheadersection.xml,xunitxml -o -,txt)
29+
30+add_dependencies(qmluitests testlistviewwithpageheader)
31+add_dependencies(qmluitests testlistviewwithpageheadersection)
tests/plugins/ListViewWithPageHeader/listviewwithpageheadertest.cppnew file+1311
@@ -0,0 +1,1311 @@
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 "listviewwithpageheader.h"
18+
19+#include <QAbstractItemModel>
20+#include <QQmlEngine>
21+#include <QQuickView>
22+#include <QtTestGui>
23+#include <private/qquicklistmodel_p.h>
24+#include <private/qquickanimation_p.h>
25+#include <private/qquickitem_p.h>
26+
27+class ListViewWithPageHeaderTest : public QObject
28+{
29+ Q_OBJECT
30+
31+private:
32+ void verifyItem(int visibleIndex, qreal pos, qreal height, bool culled)
33+ {
34+ ListViewWithPageHeader::ListItem *item = lvwph->m_visibleItems[visibleIndex];
35+ QTRY_COMPARE(item->y(), pos);
36+ QTRY_COMPARE(item->height(), height);
37+ QCOMPARE(QQuickItemPrivate::get(item->m_item)->culled, culled);
38+ }
39+
40+ void changeContentY(qreal change)
41+ {
42+ const qreal dest = lvwph->contentY() + change;
43+ if (dest > lvwph->contentY()) {
44+ const qreal jump = 25;
45+ while (lvwph->contentY() + jump < dest) {
46+ lvwph->setContentY(lvwph->contentY() + jump);
47+ QTest::qWait(1);
48+ }
49+ } else {
50+ const qreal jump = -25;
51+ while (lvwph->contentY() + jump > dest) {
52+ lvwph->setContentY(lvwph->contentY() + jump);
53+ QTest::qWait(1);
54+ }
55+ }
56+ lvwph->setContentY(dest);
57+ QTest::qWait(1);
58+ }
59+
60+ void scrollToTop()
61+ {
62+ const qreal jump = -25;
63+ while (!lvwph->isAtYBeginning()) {
64+ if (lvwph->contentY() + jump > -lvwph->minYExtent()) {
65+ lvwph->setContentY(lvwph->contentY() + jump);
66+ } else {
67+ lvwph->setContentY(lvwph->contentY() - 1);
68+ }
69+ QTest::qWait(1);
70+ }
71+ }
72+
73+ void scrollToBottom()
74+ {
75+ const qreal jump = 25;
76+ while (!lvwph->isAtYEnd()) {
77+ if (lvwph->contentY() + lvwph->height() + jump < lvwph->contentHeight()) {
78+ lvwph->setContentY(lvwph->contentY() + jump);
79+ } else {
80+ lvwph->setContentY(lvwph->contentY() + 1);
81+ }
82+ QTest::qWait(1);
83+ }
84+ }
85+
86+ void verifyInitialTopPosition()
87+ {
88+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
89+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
90+ verifyItem(0, 50., 150., false);
91+ verifyItem(1, 200., 200., false);
92+ verifyItem(2, 400., 350., false);
93+ verifyItem(3, 750., 350., true);
94+ QCOMPARE(lvwph->m_minYExtent, 0.);
95+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
96+ QCOMPARE(lvwph->m_clipItem->clip(), false);
97+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
98+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
99+ QCOMPARE(lvwph->contentY(), 0.);
100+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
101+ }
102+
103+private Q_SLOTS:
104+
105+ void initTestCase()
106+ {
107+ }
108+
109+ void init()
110+ {
111+ view = new QQuickView();
112+ view->engine()->addImportPath(BUILT_PLUGINS_DIR);
113+ view->setSource(QUrl::fromLocalFile(LISTVIEWWITHPAGEHEADER_FOLDER "/test.qml"));
114+ lvwph = dynamic_cast<ListViewWithPageHeader*>(view->rootObject()->findChild<QQuickFlickable*>());
115+ model = view->rootObject()->findChild<QQuickListModel*>();
116+ otherDelegate = view->rootObject()->findChild<QQmlComponent*>();
117+ QVERIFY(lvwph);
118+ QVERIFY(model);
119+ QVERIFY(otherDelegate);
120+ view->show();
121+ QTest::qWaitForWindowExposed(view);
122+
123+ verifyInitialTopPosition();
124+ }
125+
126+ void cleanup()
127+ {
128+ delete view;
129+ }
130+
131+ void testCreationDeletion()
132+ {
133+ // Nothing, init/cleanup already tests this
134+ }
135+
136+ void testDrag1PixelUp()
137+ {
138+ lvwph->setContentY(lvwph->contentY() + 1);
139+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
140+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
141+ verifyItem(0, 49., 150., false);
142+ verifyItem(1, 199., 200., false);
143+ verifyItem(2, 399., 350., false);
144+ verifyItem(3, 749., 350., true);
145+ QCOMPARE(lvwph->m_minYExtent, 0.);
146+ QCOMPARE(lvwph->m_clipItem->y(), 1.);
147+ QCOMPARE(lvwph->m_clipItem->clip(), false);
148+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
149+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
150+ QCOMPARE(lvwph->contentY(), 1.);
151+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
152+ }
153+
154+ void testHeaderDetachDragDown()
155+ {
156+ QTest::mousePress(view, Qt::LeftButton, Qt::NoModifier, QPoint(0, 0));
157+ QTest::qWait(100);
158+ QTest::mouseMove(view, QPoint(0, 5));
159+ QTest::qWait(100);
160+ QTest::mouseMove(view, QPoint(0, 10));
161+ QTest::qWait(100);
162+ QTest::mouseMove(view, QPoint(0, 15));
163+ QTest::qWait(100);
164+ QTest::mouseMove(view, QPoint(0, 20));
165+ QTest::qWait(100);
166+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
167+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
168+ verifyItem(0, 55., 150., false);
169+ verifyItem(1, 205., 200., false);
170+ verifyItem(2, 405., 350., false);
171+ verifyItem(3, 755., 350., true);
172+ QCOMPARE(lvwph->m_minYExtent, 0.);
173+ QCOMPARE(lvwph->m_clipItem->y(), -5.);
174+ QCOMPARE(lvwph->m_clipItem->clip(), false);
175+ QCOMPARE(lvwph->m_headerItem->y(), -5.);
176+ QCOMPARE(lvwph->m_headerItem->height(), 55.);
177+ QCOMPARE(lvwph->contentY(), -5.);
178+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
179+
180+ QTest::mouseRelease(view, Qt::LeftButton, Qt::NoModifier, QPoint(0, 15));
181+
182+ verifyInitialTopPosition();
183+ }
184+
185+ void testDrag375PixelUp()
186+ {
187+ changeContentY(375);
188+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 5);
189+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
190+ verifyItem(0, -325., 150., true);
191+ verifyItem(1, -175, 200., false);
192+ verifyItem(2, 25, 350., false);
193+ verifyItem(3, 375, 350., false);
194+ verifyItem(4, 725, 350., true);
195+ QCOMPARE(lvwph->m_minYExtent, 0.);
196+ QCOMPARE(lvwph->m_clipItem->y(), 375.);
197+ QCOMPARE(lvwph->m_clipItem->clip(), false);
198+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
199+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
200+ QCOMPARE(lvwph->contentY(), 375.);
201+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
202+ }
203+
204+ void testDrag520PixelUp()
205+ {
206+ changeContentY(520);
207+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
208+ QCOMPARE(lvwph->m_firstVisibleIndex, 1);
209+ verifyItem(0, -320., 200., true);
210+ verifyItem(1, -120, 350., false);
211+ verifyItem(2, 230, 350., false);
212+ verifyItem(3, 580, 350., true);
213+ // Just here as first check against m_minYExtent when m_firstVisibleIndex is not 0
214+ // We as humans know that m_minYExtent will be 0 but since the first delegate is not there anymore
215+ // we have to estimate its size, the average item height is 312.5 which is 162.5 more than the
216+ // "real" size of 150 and that's why the m_minYExtent has that "peculiar" value
217+ // It's fine since what it means is that we could scroll more up than the original position
218+ // but we will recalculate m_minYExtent when the item 0 is created and set it correctly
219+ QCOMPARE(lvwph->m_minYExtent, 162.5);
220+ QCOMPARE(lvwph->m_clipItem->y(), 520.);
221+ QCOMPARE(lvwph->m_clipItem->clip(), false);
222+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
223+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
224+ QCOMPARE(lvwph->contentY(), 520.);
225+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
226+ }
227+
228+ void testDragHeaderUpThenShow()
229+ {
230+ changeContentY(120);
231+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
232+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
233+ verifyItem(0, -70., 150., false);
234+ verifyItem(1, 80., 200., false);
235+ verifyItem(2, 280., 350., false);
236+ verifyItem(3, 630., 350., true);
237+ QCOMPARE(lvwph->m_minYExtent, 0.);
238+ QCOMPARE(lvwph->m_clipItem->y(), 120.);
239+ QCOMPARE(lvwph->m_clipItem->clip(), false);
240+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
241+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
242+ QCOMPARE(lvwph->contentY(), 120.);
243+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
244+
245+ changeContentY(-30);
246+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
247+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
248+ verifyItem(0, -70., 150., false);
249+ verifyItem(1, 80., 200., false);
250+ verifyItem(2, 280., 350., false);
251+ verifyItem(3, 630., 350., true);
252+ QCOMPARE(lvwph->m_minYExtent, 0.);
253+ QCOMPARE(lvwph->m_clipItem->y(), 120.);
254+ QCOMPARE(lvwph->m_clipItem->clip(), true);
255+ QTRY_COMPARE(lvwph->m_headerItem->y(), 70.);
256+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
257+ QCOMPARE(lvwph->contentY(), 90.);
258+ QCOMPARE(lvwph->m_headerItemShownHeight, 30.);
259+ }
260+
261+ void testDragHeaderUpThenShowWithoutHidingTotally()
262+ {
263+ changeContentY(10);
264+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
265+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
266+ verifyItem(0, 40., 150., false);
267+ verifyItem(1, 190., 200., false);
268+ verifyItem(2, 390., 350., false);
269+ verifyItem(3, 740., 350., true);
270+ QCOMPARE(lvwph->m_minYExtent, 0.);
271+ QCOMPARE(lvwph->m_clipItem->y(), 10.);
272+ QCOMPARE(lvwph->m_clipItem->clip(), false);
273+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
274+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
275+ QCOMPARE(lvwph->contentY(), 10.);
276+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
277+
278+ changeContentY(-1);
279+
280+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
281+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
282+ verifyItem(0, 41., 150., false);
283+ verifyItem(1, 191., 200., false);
284+ verifyItem(2, 391., 350., false);
285+ verifyItem(3, 741., 350., true);
286+ QCOMPARE(lvwph->m_minYExtent, 0.);
287+ QCOMPARE(lvwph->m_clipItem->y(), 9.);
288+ QCOMPARE(lvwph->m_clipItem->clip(), false);
289+ QTRY_COMPARE(lvwph->m_headerItem->y(), 0.);
290+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
291+ QCOMPARE(lvwph->contentY(), 9.);
292+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
293+ }
294+
295+ void testPositionAtBeginningIndex0Visible()
296+ {
297+ changeContentY(375);
298+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 5);
299+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
300+ verifyItem(0, -325., 150., true);
301+ verifyItem(1, -175, 200., false);
302+ verifyItem(2, 25, 350., false);
303+ verifyItem(3, 375, 350., false);
304+ verifyItem(4, 725, 350., true);
305+ QCOMPARE(lvwph->m_minYExtent, 0.);
306+ QCOMPARE(lvwph->m_clipItem->y(), 375.);
307+ QCOMPARE(lvwph->m_clipItem->clip(), false);
308+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
309+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
310+ QCOMPARE(lvwph->contentY(), 375.);
311+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
312+
313+ lvwph->positionAtBeginning();
314+
315+ verifyInitialTopPosition();
316+ }
317+
318+ void testPositionAtBeginningIndex0NotVisible()
319+ {
320+ changeContentY(520);
321+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
322+ QCOMPARE(lvwph->m_firstVisibleIndex, 1);
323+ verifyItem(0, -320., 200., true);
324+ verifyItem(1, -120, 350., false);
325+ verifyItem(2, 230, 350., false);
326+ verifyItem(3, 580, 350., true);
327+ QCOMPARE(lvwph->m_minYExtent, 162.5);
328+ QCOMPARE(lvwph->m_clipItem->y(), 520.);
329+ QCOMPARE(lvwph->m_clipItem->clip(), false);
330+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
331+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
332+ QCOMPARE(lvwph->contentY(), 520.);
333+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
334+
335+ lvwph->positionAtBeginning();
336+
337+ verifyInitialTopPosition();
338+ }
339+
340+ void testIndex0GrowOnScreen()
341+ {
342+ model->setProperty(0, "size", 400);
343+
344+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
345+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
346+ verifyItem(0, 50., 400., false);
347+ verifyItem(1, 450., 200., false);
348+ verifyItem(2, 650., 350., true);
349+ QCOMPARE(lvwph->m_minYExtent, 0.);
350+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
351+ QCOMPARE(lvwph->m_clipItem->clip(), false);
352+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
353+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
354+ QCOMPARE(lvwph->contentY(), 0.);
355+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
356+ }
357+
358+ void testIndex0GrowOffScreen()
359+ {
360+ changeContentY(375);
361+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 5);
362+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
363+ verifyItem(0, -325., 150., true);
364+ verifyItem(1, -175, 200., false);
365+ verifyItem(2, 25, 350., false);
366+ verifyItem(3, 375, 350., false);
367+ verifyItem(4, 725, 350., true);
368+ QCOMPARE(lvwph->m_minYExtent, 0.);
369+ QCOMPARE(lvwph->m_clipItem->y(), 375.);
370+ QCOMPARE(lvwph->m_clipItem->clip(), false);
371+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
372+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
373+ QCOMPARE(lvwph->contentY(), 375.);
374+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
375+
376+ model->setProperty(0, "size", 400);
377+
378+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 5);
379+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
380+ verifyItem(0, -575., 400., true);
381+ verifyItem(1, -175, 200., false);
382+ verifyItem(2, 25, 350., false);
383+ verifyItem(3, 375, 350., false);
384+ verifyItem(4, 725, 350., true);
385+ QCOMPARE(lvwph->m_minYExtent, 250.);
386+ QCOMPARE(lvwph->m_clipItem->y(), 375.);
387+ QCOMPARE(lvwph->m_clipItem->clip(), false);
388+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
389+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
390+ QCOMPARE(lvwph->contentY(), 375.);
391+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
392+
393+ scrollToTop();
394+
395+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
396+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
397+ verifyItem(0, 50., 400., false);
398+ verifyItem(1, 450, 200., false);
399+ verifyItem(2, 650, 350., true);
400+ QCOMPARE(lvwph->m_minYExtent, 250.);
401+ QCOMPARE(lvwph->m_clipItem->y(), -250.);
402+ QCOMPARE(lvwph->m_clipItem->clip(), false);
403+ QCOMPARE(lvwph->m_headerItem->y(), -250.);
404+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
405+ QCOMPARE(lvwph->contentY(), -250.);
406+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
407+
408+ changeContentY(30);
409+
410+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
411+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
412+ verifyItem(0, 20., 400., false);
413+ verifyItem(1, 420, 200., false);
414+ verifyItem(2, 620, 350., true);
415+ QCOMPARE(lvwph->m_minYExtent, 250.);
416+ QCOMPARE(lvwph->m_clipItem->y(), -220.);
417+ QCOMPARE(lvwph->m_clipItem->clip(), false);
418+ QCOMPARE(lvwph->m_headerItem->y(), -250.);
419+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
420+ QCOMPARE(lvwph->contentY(), -220.);
421+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
422+ }
423+
424+ void testIndex0GrowNotCreated()
425+ {
426+ changeContentY(520);
427+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
428+ QCOMPARE(lvwph->m_firstVisibleIndex, 1);
429+ verifyItem(0, -320., 200., true);
430+ verifyItem(1, -120, 350., false);
431+ verifyItem(2, 230, 350., false);
432+ verifyItem(3, 580, 350., true);
433+ QCOMPARE(lvwph->m_minYExtent, 162.5);
434+ QCOMPARE(lvwph->m_clipItem->y(), 520.);
435+ QCOMPARE(lvwph->m_clipItem->clip(), false);
436+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
437+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
438+ QCOMPARE(lvwph->contentY(), 520.);
439+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
440+
441+ model->setProperty(0, "size", 400);
442+
443+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
444+ QCOMPARE(lvwph->m_firstVisibleIndex, 1);
445+ verifyItem(0, -320., 200., true);
446+ verifyItem(1, -120, 350., false);
447+ verifyItem(2, 230, 350., false);
448+ verifyItem(3, 580, 350., true);
449+ QCOMPARE(lvwph->m_minYExtent, 162.5);
450+ QCOMPARE(lvwph->m_clipItem->y(), 520.);
451+ QCOMPARE(lvwph->m_clipItem->clip(), false);
452+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
453+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
454+ QCOMPARE(lvwph->contentY(), 520.);
455+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
456+
457+ scrollToTop();
458+
459+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
460+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
461+ verifyItem(0, 50., 400., false);
462+ verifyItem(1, 450, 200., false);
463+ verifyItem(2, 650, 350., true);
464+ QCOMPARE(lvwph->m_minYExtent, 250.);
465+ QCOMPARE(lvwph->m_clipItem->y(), -250.);
466+ QCOMPARE(lvwph->m_clipItem->clip(), false);
467+ QCOMPARE(lvwph->m_headerItem->y(), -250.);
468+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
469+ QCOMPARE(lvwph->contentY(), -250.);
470+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
471+ }
472+
473+ void testShowHideShowHeaderAtBottom()
474+ {
475+ scrollToBottom();
476+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
477+ QCOMPARE(lvwph->m_firstVisibleIndex, 3);
478+ verifyItem(0, -508., 350., true);
479+ verifyItem(1, -158, 350., false);
480+ verifyItem(2, 192, 350., false);
481+ QCOMPARE(lvwph->m_minYExtent, 350.);
482+ QCOMPARE(lvwph->m_clipItem->y(), 1258.);
483+ QCOMPARE(lvwph->m_clipItem->clip(), false);
484+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
485+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
486+ QCOMPARE(lvwph->contentY(), 1258.);
487+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
488+
489+ changeContentY(-30);
490+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
491+ QCOMPARE(lvwph->m_firstVisibleIndex, 3);
492+ verifyItem(0, -508., 350., true);
493+ verifyItem(1, -158, 350., false);
494+ verifyItem(2, 192, 350., false);
495+ QCOMPARE(lvwph->m_minYExtent, 350.);
496+ QCOMPARE(lvwph->m_clipItem->y(), 1258.);
497+ QCOMPARE(lvwph->m_clipItem->clip(), true);
498+ QCOMPARE(lvwph->m_headerItem->y(), 1208.);
499+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
500+ QCOMPARE(lvwph->contentY(), 1228.);
501+ QCOMPARE(lvwph->m_headerItemShownHeight, 30.);
502+
503+ changeContentY(30);
504+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
505+ QCOMPARE(lvwph->m_firstVisibleIndex, 3);
506+ verifyItem(0, -508., 350., true);
507+ verifyItem(1, -158, 350., false);
508+ verifyItem(2, 192, 350., false);
509+ QCOMPARE(lvwph->m_minYExtent, 350.);
510+ QCOMPARE(lvwph->m_clipItem->y(), 1258.);
511+ QCOMPARE(lvwph->m_clipItem->clip(), false);
512+ QCOMPARE(lvwph->m_headerItem->y(), -350.);
513+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
514+ QCOMPARE(lvwph->contentY(), 1258.);
515+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
516+
517+ changeContentY(-30);
518+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
519+ QCOMPARE(lvwph->m_firstVisibleIndex, 3);
520+ verifyItem(0, -508., 350., true);
521+ verifyItem(1, -158, 350., false);
522+ verifyItem(2, 192, 350., false);
523+ QCOMPARE(lvwph->m_minYExtent, 350.);
524+ QCOMPARE(lvwph->m_clipItem->y(), 1258.);
525+ QCOMPARE(lvwph->m_clipItem->clip(), true);
526+ QCOMPARE(lvwph->m_headerItem->y(), 1208.);
527+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
528+ QCOMPARE(lvwph->contentY(), 1228.);
529+ QCOMPARE(lvwph->m_headerItemShownHeight, 30.);
530+ }
531+
532+ void testChangeDelegateAtBottom()
533+ {
534+ scrollToBottom();
535+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
536+ QCOMPARE(lvwph->m_firstVisibleIndex, 3);
537+ verifyItem(0, -508., 350., true);
538+ verifyItem(1, -158, 350., false);
539+ verifyItem(2, 192, 350., false);
540+ QCOMPARE(lvwph->m_minYExtent, 350.);
541+ QCOMPARE(lvwph->m_clipItem->y(), 1258.);
542+ QCOMPARE(lvwph->m_clipItem->clip(), false);
543+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
544+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
545+ QCOMPARE(lvwph->contentY(), 1258.);
546+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
547+
548+ lvwph->setDelegate(otherDelegate);
549+
550+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 6);
551+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
552+ verifyItem(0, 50., 35., false);
553+ verifyItem(1, 85, 35., false);
554+ verifyItem(2, 120, 35., false);
555+ verifyItem(3, 155, 35., false);
556+ verifyItem(4, 190, 35., false);
557+ verifyItem(5, 225, 35., false);
558+ QCOMPARE(lvwph->m_minYExtent, 0.);
559+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
560+ QCOMPARE(lvwph->m_clipItem->clip(), false);
561+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
562+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
563+ QCOMPARE(lvwph->contentY(), 0.);
564+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
565+ }
566+
567+ void testSetEmptyHeaderAtTop()
568+ {
569+ lvwph->setHeader(nullptr);
570+
571+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
572+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
573+ verifyItem(0, 0., 150., false);
574+ verifyItem(1, 150., 200., false);
575+ verifyItem(2, 350., 350., false);
576+ verifyItem(3, 700., 350., true);
577+ QCOMPARE(lvwph->m_minYExtent, 0.);
578+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
579+ QCOMPARE(lvwph->m_clipItem->clip(), false);
580+ QCOMPARE(lvwph->m_headerItem, (QQuickItem*)nullptr);
581+ QCOMPARE(lvwph->contentY(), 0.);
582+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
583+ }
584+
585+ void testSetEmptyHeaderAtBottom()
586+ {
587+ scrollToBottom();
588+ lvwph->setHeader(nullptr);
589+
590+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
591+ QCOMPARE(lvwph->m_firstVisibleIndex, 3);
592+ verifyItem(0, -508., 350., true);
593+ verifyItem(1, -158, 350., false);
594+ verifyItem(2, 192, 350., false);
595+ QCOMPARE(lvwph->m_minYExtent, 300.);
596+ QCOMPARE(lvwph->m_clipItem->y(), 1258.);
597+ QCOMPARE(lvwph->m_clipItem->clip(), false);
598+ QCOMPARE(lvwph->m_headerItem, (QQuickItem*)nullptr);
599+ QCOMPARE(lvwph->contentY(), 1258.);
600+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
601+
602+ scrollToTop();
603+
604+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
605+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
606+ verifyItem(0, 0., 150., false);
607+ verifyItem(1, 150., 200., false);
608+ verifyItem(2, 350., 350., false);
609+ verifyItem(3, 700., 350., true);
610+ QCOMPARE(lvwph->m_minYExtent, -50.);
611+ QCOMPARE(lvwph->m_clipItem->y(), 50.);
612+ QCOMPARE(lvwph->m_clipItem->clip(), false);
613+ QCOMPARE(lvwph->m_headerItem, (QQuickItem*)nullptr);
614+ QCOMPARE(lvwph->contentY(), 50.);
615+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
616+ }
617+
618+ void testSetEmptyHeaderWhenPartlyShownClipped()
619+ {
620+ scrollToBottom();
621+ changeContentY(-30);
622+ lvwph->setHeader(nullptr);
623+
624+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
625+ QCOMPARE(lvwph->m_firstVisibleIndex, 3);
626+ verifyItem(0, -508., 350., true);
627+ verifyItem(1, -158, 350., false);
628+ verifyItem(2, 192, 350., false);
629+ QCOMPARE(lvwph->m_minYExtent, 330.);
630+ QCOMPARE(lvwph->m_clipItem->y(), 1228.);
631+ QCOMPARE(lvwph->m_clipItem->clip(), false);
632+ QCOMPARE(lvwph->m_headerItem, (QQuickItem*)nullptr);
633+ QCOMPARE(lvwph->contentY(), 1228.);
634+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
635+ QTRY_VERIFY(lvwph->isAtYEnd());
636+
637+ scrollToTop();
638+
639+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
640+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
641+ verifyItem(0, 0., 150., false);
642+ verifyItem(1, 150., 200., false);
643+ verifyItem(2, 350., 350., false);
644+ verifyItem(3, 700., 350., true);
645+ QCOMPARE(lvwph->m_minYExtent, -20.);
646+ QCOMPARE(lvwph->m_clipItem->y(), 20.);
647+ QCOMPARE(lvwph->m_clipItem->clip(), false);
648+ QCOMPARE(lvwph->m_headerItem, (QQuickItem*)nullptr);
649+ QCOMPARE(lvwph->contentY(), 20.);
650+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
651+ }
652+
653+ void testSetEmptyHeaderWhenPartlyShownNotClipped()
654+ {
655+ changeContentY(30);
656+ lvwph->setHeader(nullptr);
657+
658+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
659+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
660+ verifyItem(0, -30., 150., false);
661+ verifyItem(1, 120., 200., false);
662+ verifyItem(2, 320., 350., false);
663+ verifyItem(3, 670., 350., true);
664+ QCOMPARE(lvwph->m_minYExtent, 0.);
665+ QCOMPARE(lvwph->m_clipItem->y(), 30.);
666+ QCOMPARE(lvwph->m_clipItem->clip(), false);
667+ QCOMPARE(lvwph->m_headerItem, (QQuickItem*)nullptr);
668+ QCOMPARE(lvwph->contentY(), 30.);
669+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
670+ }
671+
672+ void testSetNullDelegate()
673+ {
674+ lvwph->setDelegate(nullptr);
675+
676+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 0);
677+ QCOMPARE(lvwph->m_firstVisibleIndex, -1);
678+ QCOMPARE(lvwph->m_minYExtent, 0.);
679+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
680+ QCOMPARE(lvwph->m_clipItem->clip(), false);
681+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
682+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
683+ QCOMPARE(lvwph->contentY(), 0.);
684+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
685+ QTRY_COMPARE(lvwph->contentHeight(), 50.);
686+ QVERIFY(lvwph->isAtYBeginning());
687+ QVERIFY(lvwph->isAtYEnd());
688+ }
689+
690+ void testInsertItems()
691+ {
692+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 100));
693+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 125));
694+
695+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 5);
696+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
697+ verifyItem(0, 50., 150., false);
698+ verifyItem(1, 200., 125., false);
699+ verifyItem(2, 325., 100., false);
700+ verifyItem(3, 425., 200., false);
701+ verifyItem(4, 625., 350., true);
702+ QCOMPARE(lvwph->m_minYExtent, 0.);
703+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
704+ QCOMPARE(lvwph->m_clipItem->clip(), false);
705+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
706+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
707+ QCOMPARE(lvwph->contentY(), 0.);
708+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
709+ }
710+
711+ void testInsertItemsOnNotShownPosition()
712+ {
713+ changeContentY(700);
714+
715+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
716+ QTRY_COMPARE(lvwph->m_firstVisibleIndex, 2);
717+ verifyItem(0, -300., 350., false);
718+ verifyItem(1, 50, 350., false);
719+ verifyItem(2, 400, 350., false);
720+ verifyItem(3, 750, 350., true);
721+ QCOMPARE(lvwph->m_minYExtent, 350.);
722+ QCOMPARE(lvwph->m_clipItem->y(), 700.);
723+ QCOMPARE(lvwph->m_clipItem->clip(), false);
724+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
725+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
726+ QCOMPARE(lvwph->contentY(), 700.);
727+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
728+
729+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 100));
730+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 125));
731+
732+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
733+ QCOMPARE(lvwph->m_firstVisibleIndex, 4);
734+ verifyItem(0, -300., 350., false);
735+ verifyItem(1, 50, 350., false);
736+ verifyItem(2, 400, 350., false);
737+ verifyItem(3, 750, 350., true);
738+ QCOMPARE(lvwph->m_minYExtent, 1050.);
739+ QCOMPARE(lvwph->m_clipItem->y(), 700.);
740+ QCOMPARE(lvwph->m_clipItem->clip(), false);
741+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
742+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
743+ QCOMPARE(lvwph->contentY(), 700.);
744+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
745+
746+ scrollToTop();
747+
748+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 5);
749+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
750+ verifyItem(0, 50., 150., false);
751+ verifyItem(1, 200., 125., false);
752+ verifyItem(2, 325., 100., false);
753+ verifyItem(3, 425., 200., false);
754+ verifyItem(4, 625., 350., true);
755+ QCOMPARE(lvwph->m_minYExtent, 225.);
756+ QCOMPARE(lvwph->m_clipItem->y(), -225.);
757+ QCOMPARE(lvwph->m_clipItem->clip(), false);
758+ QCOMPARE(lvwph->m_headerItem->y(), -225.);
759+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
760+ QCOMPARE(lvwph->contentY(), -225.);
761+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
762+ }
763+
764+ void testInsertItemsAtEndOfViewport()
765+ {
766+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 3), Q_ARG(QVariant, 100));
767+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 3), Q_ARG(QVariant, 125));
768+
769+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
770+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
771+ verifyItem(0, 50., 150., false);
772+ verifyItem(1, 200., 200., false);
773+ verifyItem(2, 400., 350., false);
774+ verifyItem(3, 750., 125., true);
775+ QCOMPARE(lvwph->m_minYExtent, 0.);
776+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
777+ QCOMPARE(lvwph->m_clipItem->clip(), false);
778+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
779+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
780+ QCOMPARE(lvwph->contentY(), 0.);
781+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
782+ }
783+
784+ void testInsertItemsBeforeValidIndex()
785+ {
786+ changeContentY(520);
787+
788+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
789+ QCOMPARE(lvwph->m_firstVisibleIndex, 1);
790+ verifyItem(0, -320., 200., true);
791+ verifyItem(1, -120, 350., false);
792+ verifyItem(2, 230, 350., false);
793+ verifyItem(3, 580, 350., true);
794+ QCOMPARE(lvwph->m_minYExtent, 162.5);
795+ QCOMPARE(lvwph->m_clipItem->y(), 520.);
796+ QCOMPARE(lvwph->m_clipItem->clip(), false);
797+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
798+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
799+ QCOMPARE(lvwph->contentY(), 520.);
800+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
801+
802+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 100));
803+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 125));
804+
805+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
806+ QCOMPARE(lvwph->m_firstVisibleIndex, 3);
807+ verifyItem(0, -320., 200., true);
808+ verifyItem(1, -120, 350., false);
809+ verifyItem(2, 230, 350., false);
810+ verifyItem(3, 580, 350., true);
811+ QCOMPARE(lvwph->m_minYExtent, 787.5);
812+ QCOMPARE(lvwph->m_clipItem->y(), 520.);
813+ QCOMPARE(lvwph->m_clipItem->clip(), false);
814+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
815+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
816+ QCOMPARE(lvwph->contentY(), 520.);
817+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
818+ }
819+
820+ void testInsertItemsBeforeViewport()
821+ {
822+ changeContentY(375);
823+
824+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 5);
825+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
826+ verifyItem(0, -325., 150., true);
827+ verifyItem(1, -175, 200., false);
828+ verifyItem(2, 25, 350., false);
829+ verifyItem(3, 375, 350., false);
830+ verifyItem(4, 725, 350., true);
831+ QCOMPARE(lvwph->m_minYExtent, 0.);
832+ QCOMPARE(lvwph->m_clipItem->y(), 375.);
833+ QCOMPARE(lvwph->m_clipItem->clip(), false);
834+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
835+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
836+ QCOMPARE(lvwph->contentY(), 375.);
837+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
838+
839+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 100));
840+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 125));
841+
842+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 5);
843+ QCOMPARE(lvwph->m_firstVisibleIndex, 2);
844+ verifyItem(0, -275., 100., true);
845+ verifyItem(1, -175, 200., false);
846+ verifyItem(2, 25, 350., false);
847+ verifyItem(3, 375, 350., false);
848+ verifyItem(4, 725, 350., true);
849+ QCOMPARE(lvwph->m_minYExtent, 490.);
850+ QCOMPARE(lvwph->m_clipItem->y(), 375.);
851+ QCOMPARE(lvwph->m_clipItem->clip(), false);
852+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
853+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
854+ QCOMPARE(lvwph->contentY(), 375.);
855+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
856+
857+ scrollToTop();
858+
859+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 5);
860+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
861+ verifyItem(0, 50., 150., false);
862+ verifyItem(1, 200., 125., false);
863+ verifyItem(2, 325., 100., false);
864+ verifyItem(3, 425., 200., false);
865+ verifyItem(4, 625., 350., true);
866+ QCOMPARE(lvwph->m_minYExtent, 225.);
867+ QCOMPARE(lvwph->m_clipItem->y(), -225.);
868+ QCOMPARE(lvwph->m_clipItem->clip(), false);
869+ QCOMPARE(lvwph->m_headerItem->y(), -225.);
870+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
871+ QCOMPARE(lvwph->contentY(), -225.);
872+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
873+ }
874+
875+ void testInsertItemsAtBottom()
876+ {
877+ scrollToBottom();
878+
879+ QVERIFY(lvwph->isAtYEnd());
880+
881+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 100));
882+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 125));
883+
884+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 5);
885+ QCOMPARE(lvwph->m_firstVisibleIndex, 3);
886+ verifyItem(0, -508., 350., true);
887+ verifyItem(1, -158, 350., false);
888+ verifyItem(2, 192, 350., false);
889+ verifyItem(3, 542, 125., true);
890+ verifyItem(4, 667, 100., true);
891+ QCOMPARE(lvwph->m_minYExtent, 65.);
892+ QCOMPARE(lvwph->m_clipItem->y(), 1258.);
893+ QCOMPARE(lvwph->m_clipItem->clip(), false);
894+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
895+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
896+ QCOMPARE(lvwph->contentY(), 1258.);
897+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
898+ QVERIFY(!lvwph->isAtYEnd());
899+
900+ scrollToBottom();
901+
902+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
903+ QCOMPARE(lvwph->m_firstVisibleIndex, 4);
904+ verifyItem(0, -383., 350., true);
905+ verifyItem(1, -33, 350., false);
906+ verifyItem(2, 317, 125., false);
907+ verifyItem(3, 442, 100., false);
908+ QCOMPARE(lvwph->m_minYExtent, -125.);
909+ QCOMPARE(lvwph->m_clipItem->y(), 1483.);
910+ QCOMPARE(lvwph->m_clipItem->clip(), false);
911+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
912+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
913+ QCOMPARE(lvwph->contentY(), 1483.);
914+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
915+ QVERIFY(lvwph->isAtYEnd());
916+ }
917+
918+ void testInsertItemAtTop()
919+ {
920+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75));
921+
922+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
923+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
924+ verifyItem(0, 50., 75., false);
925+ verifyItem(1, 125., 150., false);
926+ verifyItem(2, 275., 200., false);
927+ verifyItem(3, 475., 350., false);
928+ QCOMPARE(lvwph->m_minYExtent, 0.);
929+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
930+ QCOMPARE(lvwph->m_clipItem->clip(), false);
931+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
932+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
933+ QCOMPARE(lvwph->contentY(), 0.);
934+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
935+ QVERIFY(lvwph->isAtYBeginning());
936+ }
937+
938+ void testInsertItem10SmallItemsAtTopWhenAtBottom()
939+ {
940+ scrollToBottom();
941+
942+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75));
943+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75));
944+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75));
945+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75));
946+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75));
947+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75));
948+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75));
949+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75));
950+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75));
951+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75));
952+
953+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
954+ QCOMPARE(lvwph->m_firstVisibleIndex, 13);
955+ verifyItem(0, -508., 350., true);
956+ verifyItem(1, -158, 350., false);
957+ verifyItem(2, 192, 350., false);
958+ QCOMPARE(lvwph->m_minYExtent, 3850.);
959+ QCOMPARE(lvwph->m_clipItem->y(), 1258.);
960+ QCOMPARE(lvwph->m_clipItem->clip(), false);
961+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
962+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
963+ QCOMPARE(lvwph->contentY(), 1258.);
964+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
965+
966+ changeContentY(-1700);
967+
968+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 12);
969+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
970+ verifyItem(0, -308., 75., true);
971+ verifyItem(1, -233., 75., true);
972+ verifyItem(2, -158., 75., true);
973+ verifyItem(3, -83., 75., true);
974+ verifyItem(4, -8., 75., false);
975+ verifyItem(5, 67., 75., false);
976+ verifyItem(6, 142., 75., false);
977+ verifyItem(7, 217., 75., false);
978+ verifyItem(8, 292., 75., false);
979+ verifyItem(9, 367., 75., false);
980+ verifyItem(10, 442., 150., false);
981+ verifyItem(11, 592., 200., true);
982+ QCOMPARE(lvwph->m_minYExtent, 750.);
983+ QCOMPARE(lvwph->m_clipItem->y(), -392.);
984+ QCOMPARE(lvwph->m_clipItem->clip(), true);
985+ QCOMPARE(lvwph->m_headerItem->y(), -442.);
986+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
987+ QCOMPARE(lvwph->contentY(), -442.);
988+ QCOMPARE(lvwph->m_headerItemShownHeight, 50.);
989+ }
990+
991+ void testRemoveItemsAtTop()
992+ {
993+ QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 2));
994+
995+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
996+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
997+ verifyItem(0, 50., 350., false);
998+ verifyItem(1, 400., 350., false);
999+ verifyItem(2, 750., 350., true);
1000+ QCOMPARE(lvwph->m_minYExtent, 0.);
1001+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
1002+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1003+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1004+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1005+ QCOMPARE(lvwph->contentY(), 0.);
1006+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1007+ QVERIFY(lvwph->isAtYBeginning());
1008+ }
1009+
1010+ void testRemoveNonCreatedItemsAtTopWhenAtBottom()
1011+ {
1012+ scrollToBottom();
1013+
1014+ QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 2));
1015+
1016+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
1017+ QCOMPARE(lvwph->m_firstVisibleIndex, 1);
1018+ verifyItem(0, -508., 350., true);
1019+ verifyItem(1, -158, 350., false);
1020+ verifyItem(2, 192, 350., false);
1021+ QCOMPARE(lvwph->m_minYExtent, -350.);
1022+ QCOMPARE(lvwph->m_clipItem->y(), 1258.);
1023+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1024+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1025+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1026+ QCOMPARE(lvwph->contentY(), 1258.);
1027+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1028+ }
1029+
1030+ void testRemoveLastItemsAtBottom()
1031+ {
1032+ scrollToBottom();
1033+
1034+ QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 4), Q_ARG(QVariant, 2));
1035+
1036+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
1037+ QCOMPARE(lvwph->m_firstVisibleIndex, 1);
1038+ verifyItem(0, -358., 200., true);
1039+ verifyItem(1, -158, 350., false);
1040+ verifyItem(2, 192, 350., false);
1041+ QCOMPARE(lvwph->m_minYExtent, 150.);
1042+ QCOMPARE(lvwph->m_clipItem->y(), 558.);
1043+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1044+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1045+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1046+ QCOMPARE(lvwph->contentY(), 558.);
1047+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1048+ }
1049+
1050+ void testRemoveItemOutOfViewport()
1051+ {
1052+ changeContentY(520);
1053+
1054+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
1055+ QCOMPARE(lvwph->m_firstVisibleIndex, 1);
1056+ verifyItem(0, -320., 200., true);
1057+ verifyItem(1, -120, 350., false);
1058+ verifyItem(2, 230, 350., false);
1059+ verifyItem(3, 580, 350., true);
1060+ QCOMPARE(lvwph->m_minYExtent, 162.5);
1061+ QCOMPARE(lvwph->m_clipItem->y(), 520.);
1062+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1063+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1064+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1065+ QCOMPARE(lvwph->contentY(), 520.);
1066+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1067+
1068+
1069+ QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 1), Q_ARG(QVariant, 1));
1070+
1071+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
1072+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1073+ verifyItem(0, -270., 150., true);
1074+ verifyItem(1, -120., 350., false);
1075+ verifyItem(2, 230, 350., false);
1076+ verifyItem(3, 580, 350., true);
1077+ QCOMPARE(lvwph->m_minYExtent, -200.);
1078+ QCOMPARE(lvwph->m_clipItem->y(), 520.);
1079+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1080+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1081+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1082+ QCOMPARE(lvwph->contentY(), 520.);
1083+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1084+ }
1085+
1086+ void testMoveFirstItems()
1087+ {
1088+ QMetaObject::invokeMethod(model, "moveItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 1), Q_ARG(QVariant, 1));
1089+
1090+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
1091+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1092+ verifyItem(0, 50., 200., false);
1093+ verifyItem(1, 250., 150., false);
1094+ verifyItem(2, 400., 350., false);
1095+ verifyItem(3, 750., 350., true);
1096+ QCOMPARE(lvwph->m_minYExtent, 0.);
1097+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
1098+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1099+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1100+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1101+ QCOMPARE(lvwph->contentY(), 0.);
1102+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1103+
1104+ }
1105+
1106+ void testMoveFirstOutOfVisibleItems()
1107+ {
1108+ QMetaObject::invokeMethod(model, "moveItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 4), Q_ARG(QVariant, 1));
1109+
1110+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
1111+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1112+ verifyItem(0, 50., 200., false);
1113+ verifyItem(1, 250., 350., false);
1114+ verifyItem(2, 600., 350., true);
1115+ QCOMPARE(lvwph->m_minYExtent, 0.);
1116+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
1117+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1118+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1119+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1120+ QCOMPARE(lvwph->contentY(), 0.);
1121+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1122+
1123+ }
1124+
1125+ void testMoveFirstToLastAtBottom()
1126+ {
1127+ scrollToBottom();
1128+
1129+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
1130+ QCOMPARE(lvwph->m_firstVisibleIndex, 3);
1131+ verifyItem(0, -508., 350., true);
1132+ verifyItem(1, -158, 350., false);
1133+ verifyItem(2, 192, 350., false);
1134+ QCOMPARE(lvwph->m_minYExtent, 350.);
1135+ QCOMPARE(lvwph->m_clipItem->y(), 1258.);
1136+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1137+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1138+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1139+ QCOMPARE(lvwph->contentY(), 1258.);
1140+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1141+
1142+ QMetaObject::invokeMethod(model, "moveItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 5), Q_ARG(QVariant, 1));
1143+
1144+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
1145+ QCOMPARE(lvwph->m_firstVisibleIndex, 2);
1146+ verifyItem(0, -508., 350., true);
1147+ verifyItem(1, -158, 350., false);
1148+ verifyItem(2, 192, 350., false);
1149+ verifyItem(3, 542, 150., true);
1150+ QCOMPARE(lvwph->m_minYExtent, -100.);
1151+ QCOMPARE(lvwph->m_clipItem->y(), 1258.);
1152+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1153+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1154+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1155+ QCOMPARE(lvwph->contentY(), 1258.);
1156+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1157+ QVERIFY(!lvwph->isAtYEnd());
1158+ }
1159+
1160+ void testChangeSizeVisibleItemNotOnViewport()
1161+ {
1162+ changeContentY(440);
1163+
1164+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 5);
1165+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1166+ verifyItem(0, -390., 150., true);
1167+ verifyItem(1, -240., 200., true);
1168+ verifyItem(2, -40, 350., false);
1169+ verifyItem(3, 310, 350., false);
1170+ verifyItem(4, 660, 350., true);
1171+ QCOMPARE(lvwph->m_minYExtent, 0.);
1172+ QCOMPARE(lvwph->m_clipItem->y(), 440.);
1173+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1174+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1175+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1176+ QCOMPARE(lvwph->contentY(), 440.);
1177+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1178+
1179+ model->setProperty(1, "size", 100);
1180+
1181+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 5);
1182+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1183+ verifyItem(0, -290., 150., true);
1184+ verifyItem(1, -140., 100., true);
1185+ verifyItem(2, -40, 350., false);
1186+ verifyItem(3, 310, 350., false);
1187+ verifyItem(4, 660, 350., true);
1188+ QCOMPARE(lvwph->m_minYExtent, -100.);
1189+ QCOMPARE(lvwph->m_clipItem->y(), 440.);
1190+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1191+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1192+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1193+ QCOMPARE(lvwph->contentY(), 440.);
1194+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1195+ }
1196+
1197+ void testShowHeaderCloseToTheTop()
1198+ {
1199+ changeContentY(375);
1200+
1201+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 5);
1202+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1203+ verifyItem(0, -325., 150., true);
1204+ verifyItem(1, -175, 200., false);
1205+ verifyItem(2, 25, 350., false);
1206+ verifyItem(3, 375, 350., false);
1207+ verifyItem(4, 725, 350., true);
1208+ QCOMPARE(lvwph->m_minYExtent, 0.);
1209+ QCOMPARE(lvwph->m_clipItem->y(), 375.);
1210+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1211+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1212+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1213+ QCOMPARE(lvwph->contentY(), 375.);
1214+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);;
1215+
1216+ lvwph->showHeader();
1217+
1218+ QTRY_VERIFY(!lvwph->m_headerShowAnimation->isRunning());
1219+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 5);
1220+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1221+ verifyItem(0, -375., 150., true);
1222+ verifyItem(1, -225, 200., true);
1223+ verifyItem(2, -25, 350., false);
1224+ verifyItem(3, 325, 350., false);
1225+ verifyItem(4, 675, 350., true);
1226+ QCOMPARE(lvwph->m_minYExtent, 50.);
1227+ QCOMPARE(lvwph->m_clipItem->y(), 375.);
1228+ QCOMPARE(lvwph->m_clipItem->clip(), true);
1229+ QCOMPARE(lvwph->m_headerItem->y(), 325.);
1230+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1231+ QCOMPARE(lvwph->contentY(), 325.);
1232+ QCOMPARE(lvwph->m_headerItemShownHeight, 50.);;
1233+
1234+ scrollToTop();
1235+
1236+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
1237+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1238+ verifyItem(0, 50., 150., false);
1239+ verifyItem(1, 200., 200., false);
1240+ verifyItem(2, 400., 350., false);
1241+ verifyItem(3, 750., 350., true);
1242+ QCOMPARE(lvwph->m_minYExtent, 50.);
1243+ QCOMPARE(lvwph->m_clipItem->y(), -50.);
1244+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1245+ QCOMPARE(lvwph->m_headerItem->y(), -50.);
1246+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1247+ QCOMPARE(lvwph->contentY(), -50.);
1248+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1249+ }
1250+
1251+ void testShowHeaderAtBottom()
1252+ {
1253+ scrollToBottom();
1254+
1255+ lvwph->showHeader();
1256+
1257+ QTRY_VERIFY(!lvwph->m_headerShowAnimation->isRunning());
1258+ QTRY_VERIFY (lvwph->isAtYEnd());
1259+ }
1260+
1261+ void growWindow()
1262+ {
1263+ view->rootObject()->setHeight(850);
1264+
1265+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 5);
1266+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1267+ verifyItem(0, 50., 150., false);
1268+ verifyItem(1, 200., 200., false);
1269+ verifyItem(2, 400., 350., false);
1270+ verifyItem(3, 750., 350., false);
1271+ verifyItem(4, 1100., 350., true);
1272+ QCOMPARE(lvwph->m_minYExtent, 0.);
1273+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
1274+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1275+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1276+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1277+ QCOMPARE(lvwph->contentY(), 0.);
1278+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1279+ }
1280+
1281+ void growWindowAtBottom()
1282+ {
1283+ scrollToBottom();
1284+
1285+ view->rootObject()->setHeight(850);
1286+
1287+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
1288+ QCOMPARE(lvwph->m_firstVisibleIndex, 2);
1289+ verifyItem(0, -550., 350., true);
1290+ verifyItem(1, -200., 350., false);
1291+ verifyItem(2, 150, 350., false);
1292+ verifyItem(3, 500, 350., false);
1293+ QCOMPARE(lvwph->m_minYExtent, 350.);
1294+ QCOMPARE(lvwph->m_clipItem->y(), 950.);
1295+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1296+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1297+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1298+ QCOMPARE(lvwph->contentY(), 950.);
1299+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1300+ }
1301+
1302+private:
1303+ QQuickView *view;
1304+ ListViewWithPageHeader *lvwph;
1305+ QQuickListModel *model;
1306+ QQmlComponent *otherDelegate;
1307+};
1308+
1309+QTEST_MAIN(ListViewWithPageHeaderTest)
1310+
1311+#include "listviewwithpageheadertest.moc"
tests/plugins/ListViewWithPageHeader/listviewwithpageheadertestsection.cppnew file+1567
@@ -0,0 +1,1567 @@
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 "listviewwithpageheader.h"
18+
19+#include <QAbstractItemModel>
20+#include <QQmlEngine>
21+#include <QQuickView>
22+#include <QtTestGui>
23+#include <private/qquicklistmodel_p.h>
24+#include <private/qquickanimation_p.h>
25+#include <private/qquickitem_p.h>
26+
27+class ListViewWithPageHeaderTestSection : public QObject
28+{
29+ Q_OBJECT
30+
31+private:
32+ void verifyItem(int visibleIndex, qreal pos, qreal height, bool culled, const QString &sectionHeader, bool sectionHeaderCulled)
33+ {
34+ QTRY_VERIFY(visibleIndex < lvwph->m_visibleItems.count());
35+ QTRY_COMPARE(lvwph->m_visibleItems[visibleIndex]->y(), pos);
36+ QTRY_COMPARE(lvwph->m_visibleItems[visibleIndex]->height(), height);
37+ QCOMPARE(QQuickItemPrivate::get(lvwph->m_visibleItems[visibleIndex]->m_item)->culled, culled);
38+ QCOMPARE(section(lvwph->m_visibleItems[visibleIndex]->m_sectionItem), sectionHeader);
39+ if (!sectionHeader.isNull()) {
40+ QCOMPARE(QQuickItemPrivate::get(lvwph->m_visibleItems[visibleIndex]->m_sectionItem)->culled, sectionHeaderCulled);
41+ }
42+ }
43+
44+ void changeContentY(qreal change)
45+ {
46+ const qreal dest = lvwph->contentY() + change;
47+ if (dest > lvwph->contentY()) {
48+ const qreal jump = 25;
49+ while (lvwph->contentY() + jump < dest) {
50+ lvwph->setContentY(lvwph->contentY() + jump);
51+ QTest::qWait(1);
52+ }
53+ } else {
54+ const qreal jump = -25;
55+ while (lvwph->contentY() + jump > dest) {
56+ lvwph->setContentY(lvwph->contentY() + jump);
57+ QTest::qWait(1);
58+ }
59+ }
60+ lvwph->setContentY(dest);
61+ QTest::qWait(1);
62+ }
63+
64+ void scrollToTop()
65+ {
66+ const qreal jump = -25;
67+ while (!lvwph->isAtYBeginning()) {
68+ if (lvwph->contentY() + jump > -lvwph->minYExtent()) {
69+ lvwph->setContentY(lvwph->contentY() + jump);
70+ } else {
71+ lvwph->setContentY(lvwph->contentY() - 1);
72+ }
73+ QTest::qWait(1);
74+ }
75+ }
76+
77+ void scrollToBottom()
78+ {
79+ const qreal jump = 25;
80+ while (!lvwph->isAtYEnd()) {
81+ if (lvwph->contentY() + lvwph->height() + jump < lvwph->contentHeight()) {
82+ lvwph->setContentY(lvwph->contentY() + jump);
83+ } else {
84+ lvwph->setContentY(lvwph->contentY() + 1);
85+ }
86+ QTest::qWait(1);
87+ }
88+ }
89+
90+ void verifyInitialTopPosition()
91+ {
92+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
93+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
94+ verifyItem(0, 50., 190., false, "Agressive", false);
95+ verifyItem(1, 240., 240., false, "Regular", false);
96+ verifyItem(2, 480., 390., false, "Mild", false);
97+ QCOMPARE(lvwph->m_minYExtent, 0.);
98+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
99+ QCOMPARE(lvwph->m_clipItem->clip(), false);
100+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
101+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
102+ QCOMPARE(lvwph->contentY(), 0.);
103+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
104+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
105+ }
106+
107+ QString section(QQuickItem *item)
108+ {
109+ return item ? QQmlEngine::contextForObject(item)->parentContext()->contextProperty(QLatin1String("section")).toString() : QString();
110+ }
111+
112+private Q_SLOTS:
113+
114+ void initTestCase()
115+ {
116+ }
117+
118+ void init()
119+ {
120+ view = new QQuickView();
121+ view->engine()->addImportPath(BUILT_PLUGINS_DIR);
122+ view->setSource(QUrl::fromLocalFile(LISTVIEWWITHPAGEHEADER_FOLDER "/test_section.qml"));
123+ lvwph = dynamic_cast<ListViewWithPageHeader*>(view->rootObject()->findChild<QQuickFlickable*>());
124+ model = view->rootObject()->findChild<QQuickListModel*>();
125+ otherDelegate = view->rootObject()->findChild<QQmlComponent*>();
126+ QVERIFY(lvwph);
127+ QVERIFY(model);
128+ QVERIFY(otherDelegate);
129+ view->show();
130+ QTest::qWaitForWindowExposed(view);
131+
132+ verifyInitialTopPosition();
133+ }
134+
135+ void cleanup()
136+ {
137+ delete view;
138+ }
139+
140+ void testCreationDeletion()
141+ {
142+ // Nothing, init/cleanup already tests this
143+ }
144+
145+ void testDrag1PixelUp()
146+ {
147+ lvwph->setContentY(lvwph->contentY() + 1);
148+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
149+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
150+ verifyItem(0, 49., 190., false, "Agressive", false);
151+ verifyItem(1, 239., 240., false, "Regular", false);
152+ verifyItem(2, 479., 390., false, "Mild", false);
153+ QCOMPARE(lvwph->m_minYExtent, 0.);
154+ QCOMPARE(lvwph->m_clipItem->y(), 1.);
155+ QCOMPARE(lvwph->m_clipItem->clip(), false);
156+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
157+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
158+ QCOMPARE(lvwph->contentY(), 1.);
159+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
160+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
161+ }
162+
163+ void testHeaderDetachDragDown()
164+ {
165+ QTest::mousePress(view, Qt::LeftButton, Qt::NoModifier, QPoint(0, 0));
166+ QTest::qWait(100);
167+ QTest::mouseMove(view, QPoint(0, 5));
168+ QTest::qWait(100);
169+ QTest::mouseMove(view, QPoint(0, 10));
170+ QTest::qWait(100);
171+ QTest::mouseMove(view, QPoint(0, 15));
172+ QTest::qWait(100);
173+ QTest::mouseMove(view, QPoint(0, 20));
174+ QTest::qWait(100);
175+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
176+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
177+ verifyItem(0, 55., 190., false, "Agressive", false);
178+ verifyItem(1, 245., 240., false, "Regular", false);
179+ verifyItem(2, 485., 390., false, "Mild", false);
180+ QCOMPARE(lvwph->m_minYExtent, 0.);
181+ QCOMPARE(lvwph->m_clipItem->y(), -5.);
182+ QCOMPARE(lvwph->m_clipItem->clip(), false);
183+ QCOMPARE(lvwph->m_headerItem->y(), -5.);
184+ QCOMPARE(lvwph->m_headerItem->height(), 55.);
185+ QCOMPARE(lvwph->contentY(), -5.);
186+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
187+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
188+
189+ QTest::mouseRelease(view, Qt::LeftButton, Qt::NoModifier, QPoint(0, 15));
190+
191+ verifyInitialTopPosition();
192+ }
193+
194+ void testDrag375PixelUp()
195+ {
196+ changeContentY(375);
197+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
198+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
199+ verifyItem(0, -325., 190., true, "Agressive", true);
200+ verifyItem(1, -135, 240., false, "Regular", true);
201+ verifyItem(2, 105, 390., false, "Mild", false);
202+ verifyItem(3, 495, 390., false, "Bold", false);
203+ QCOMPARE(lvwph->m_minYExtent, 0.);
204+ QCOMPARE(lvwph->m_clipItem->y(), 375.);
205+ QCOMPARE(lvwph->m_clipItem->clip(), false);
206+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
207+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
208+ QCOMPARE(lvwph->contentY(), 375.);
209+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
210+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
211+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
212+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
213+ }
214+
215+ void testDrag520PixelUp()
216+ {
217+ changeContentY(520);
218+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
219+ QCOMPARE(lvwph->m_firstVisibleIndex, 1);
220+ verifyItem(0, -280., 240., true, "Regular", true);
221+ verifyItem(1, -40, 390., false, "Mild", true);
222+ verifyItem(2, 350, 390., false, "Bold", false);
223+ verifyItem(3, 740, 350., true, QString(), true);
224+ QCOMPARE(lvwph->m_minYExtent, 152.5);
225+ QCOMPARE(lvwph->m_clipItem->y(), 520.);
226+ QCOMPARE(lvwph->m_clipItem->clip(), false);
227+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
228+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
229+ QCOMPARE(lvwph->contentY(), 520.);
230+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
231+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
232+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
233+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
234+ }
235+
236+ void testDragHeaderUpThenShow()
237+ {
238+ changeContentY(120);
239+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
240+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
241+ verifyItem(0, -70., 190., false, "Agressive", true);
242+ verifyItem(1, 120., 240., false, "Regular", false);
243+ verifyItem(2, 360., 390., false, "Mild", false);
244+ verifyItem(3, 750., 390., true, "Bold", true);
245+ QCOMPARE(lvwph->m_minYExtent, 0.);
246+ QCOMPARE(lvwph->m_clipItem->y(), 120.);
247+ QCOMPARE(lvwph->m_clipItem->clip(), false);
248+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
249+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
250+ QCOMPARE(lvwph->contentY(), 120.);
251+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
252+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
253+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Agressive"));
254+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
255+
256+ changeContentY(-30);
257+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
258+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
259+ verifyItem(0, -70., 190., false, "Agressive", true);
260+ verifyItem(1, 120., 240., false, "Regular", false);
261+ verifyItem(2, 360., 390., false, "Mild", false);
262+ verifyItem(3, 750., 390., true, "Bold", true);
263+ QCOMPARE(lvwph->m_minYExtent, 0.);
264+ QCOMPARE(lvwph->m_clipItem->y(), 120.);
265+ QCOMPARE(lvwph->m_clipItem->clip(), true);
266+ QTRY_COMPARE(lvwph->m_headerItem->y(), 70.);
267+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
268+ QCOMPARE(lvwph->contentY(), 90.);
269+ QCOMPARE(lvwph->m_headerItemShownHeight, 30.);
270+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
271+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Agressive"));
272+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
273+ }
274+
275+ void testDragHeaderUpThenShowWithoutHidingTotally()
276+ {
277+ changeContentY(10);
278+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
279+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
280+ verifyItem(0, 40., 190., false, "Agressive", false);
281+ verifyItem(1, 230., 240., false, "Regular", false);
282+ verifyItem(2, 470., 390., false, "Mild", false);
283+ QCOMPARE(lvwph->m_minYExtent, 0.);
284+ QCOMPARE(lvwph->m_clipItem->y(), 10.);
285+ QCOMPARE(lvwph->m_clipItem->clip(), false);
286+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
287+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
288+ QCOMPARE(lvwph->contentY(), 10.);
289+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
290+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
291+
292+ changeContentY(-1);
293+
294+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
295+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
296+ verifyItem(0, 41., 190., false, "Agressive", false);
297+ verifyItem(1, 231., 240., false, "Regular", false);
298+ verifyItem(2, 471., 390., false, "Mild", false);
299+ QCOMPARE(lvwph->m_minYExtent, 0.);
300+ QCOMPARE(lvwph->m_clipItem->y(), 9.);
301+ QCOMPARE(lvwph->m_clipItem->clip(), false);
302+ QTRY_COMPARE(lvwph->m_headerItem->y(), 0.);
303+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
304+ QCOMPARE(lvwph->contentY(), 9.);
305+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
306+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
307+ }
308+
309+ void testPositionAtBeginningIndex0Visible()
310+ {
311+ changeContentY(375);
312+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
313+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
314+ verifyItem(0, -325., 190., true, "Agressive", true);
315+ verifyItem(1, -135, 240., false, "Regular", true);
316+ verifyItem(2, 105, 390., false, "Mild", false);
317+ verifyItem(3, 495, 390., false, "Bold", false);
318+ QCOMPARE(lvwph->m_minYExtent, 0.);
319+ QCOMPARE(lvwph->m_clipItem->y(), 375.);
320+ QCOMPARE(lvwph->m_clipItem->clip(), false);
321+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
322+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
323+ QCOMPARE(lvwph->contentY(), 375.);
324+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
325+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
326+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
327+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
328+
329+ lvwph->positionAtBeginning();
330+
331+ verifyInitialTopPosition();
332+ }
333+
334+ void testPositionAtBeginningIndex0NotVisible()
335+ {
336+ changeContentY(520);
337+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
338+ QCOMPARE(lvwph->m_firstVisibleIndex, 1);
339+ verifyItem(0, -280., 240., true, "Regular", true);
340+ verifyItem(1, -40, 390., false, "Mild", true);
341+ verifyItem(2, 350, 390., false, "Bold", false);
342+ verifyItem(3, 740, 350., true, QString(), true);
343+ QCOMPARE(lvwph->m_minYExtent, 152.5);
344+ QCOMPARE(lvwph->m_clipItem->y(), 520.);
345+ QCOMPARE(lvwph->m_clipItem->clip(), false);
346+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
347+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
348+ QCOMPARE(lvwph->contentY(), 520.);
349+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
350+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
351+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
352+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
353+
354+ lvwph->positionAtBeginning();
355+
356+ verifyInitialTopPosition();
357+ }
358+
359+ void testIndex0GrowOnScreen()
360+ {
361+ model->setProperty(0, "size", 400);
362+
363+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
364+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
365+ verifyItem(0, 50., 440., false, "Agressive", false);
366+ verifyItem(1, 490., 240., false, "Regular", false);
367+ verifyItem(2, 730., 390., true, "Mild", true);
368+ QCOMPARE(lvwph->m_minYExtent, 0.);
369+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
370+ QCOMPARE(lvwph->m_clipItem->clip(), false);
371+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
372+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
373+ QCOMPARE(lvwph->contentY(), 0.);
374+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
375+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
376+ }
377+
378+ void testIndex0GrowOffScreen()
379+ {
380+ changeContentY(375);
381+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
382+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
383+ verifyItem(0, -325., 190., true, "Agressive", true);
384+ verifyItem(1, -135, 240., false, "Regular", true);
385+ verifyItem(2, 105, 390., false, "Mild", false);
386+ verifyItem(3, 495, 390., false, "Bold", false);
387+ QCOMPARE(lvwph->m_minYExtent, 0.);
388+ QCOMPARE(lvwph->m_clipItem->y(), 375.);
389+ QCOMPARE(lvwph->m_clipItem->clip(), false);
390+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
391+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
392+ QCOMPARE(lvwph->contentY(), 375.);
393+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
394+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
395+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
396+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
397+
398+ model->setProperty(0, "size", 400);
399+
400+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
401+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
402+ verifyItem(0, -575., 440., true, "Agressive", true);
403+ verifyItem(1, -135, 240., false, "Regular", true);
404+ verifyItem(2, 105, 390., false, "Mild", false);
405+ verifyItem(3, 495, 390., false, "Bold", false);
406+ QCOMPARE(lvwph->m_minYExtent, 250.);
407+ QCOMPARE(lvwph->m_clipItem->y(), 375.);
408+ QCOMPARE(lvwph->m_clipItem->clip(), false);
409+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
410+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
411+ QCOMPARE(lvwph->contentY(), 375.);
412+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
413+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
414+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
415+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
416+
417+ scrollToTop();
418+
419+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
420+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
421+ verifyItem(0, 50., 440., false, "Agressive", false);
422+ verifyItem(1, 490, 240., false, "Regular", false);
423+ verifyItem(2, 730, 390., true, "Mild", true);
424+ QCOMPARE(lvwph->m_minYExtent, 250.);
425+ QCOMPARE(lvwph->m_clipItem->y(), -250.);
426+ QCOMPARE(lvwph->m_clipItem->clip(), false);
427+ QCOMPARE(lvwph->m_headerItem->y(), -250.);
428+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
429+ QCOMPARE(lvwph->contentY(), -250.);
430+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
431+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
432+
433+ changeContentY(30);
434+
435+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
436+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
437+ verifyItem(0, 20., 440., false, "Agressive", false);
438+ verifyItem(1, 460, 240., false, "Regular", false);
439+ verifyItem(2, 700, 390., true, "Mild", true);
440+ QCOMPARE(lvwph->m_minYExtent, 250.);
441+ QCOMPARE(lvwph->m_clipItem->y(), -220.);
442+ QCOMPARE(lvwph->m_clipItem->clip(), false);
443+ QCOMPARE(lvwph->m_headerItem->y(), -250.);
444+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
445+ QCOMPARE(lvwph->contentY(), -220.);
446+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
447+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
448+ }
449+
450+ void testIndex0GrowNotCreated()
451+ {
452+ changeContentY(520);
453+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
454+ QCOMPARE(lvwph->m_firstVisibleIndex, 1);
455+ verifyItem(0, -280., 240., true, "Regular", true);
456+ verifyItem(1, -40, 390., false, "Mild", true);
457+ verifyItem(2, 350, 390., false, "Bold", false);
458+ verifyItem(3, 740, 350., true, QString(), true);
459+ QCOMPARE(lvwph->m_minYExtent, 152.5);
460+ QCOMPARE(lvwph->m_clipItem->y(), 520.);
461+ QCOMPARE(lvwph->m_clipItem->clip(), false);
462+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
463+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
464+ QCOMPARE(lvwph->contentY(), 520.);
465+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
466+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
467+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
468+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
469+
470+ model->setProperty(0, "size", 400);
471+
472+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
473+ QCOMPARE(lvwph->m_firstVisibleIndex, 1);
474+ verifyItem(0, -280., 240., true, "Regular", true);
475+ verifyItem(1, -40, 390., false, "Mild", true);
476+ verifyItem(2, 350, 390., false, "Bold", false);
477+ verifyItem(3, 740, 350., true, QString(), true);
478+ QCOMPARE(lvwph->m_minYExtent, 152.5);
479+ QCOMPARE(lvwph->m_clipItem->y(), 520.);
480+ QCOMPARE(lvwph->m_clipItem->clip(), false);
481+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
482+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
483+ QCOMPARE(lvwph->contentY(), 520.);
484+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
485+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
486+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
487+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
488+
489+ scrollToTop();
490+
491+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
492+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
493+ verifyItem(0, 50., 440., false, "Agressive", false);
494+ verifyItem(1, 490, 240., false, "Regular", false);
495+ verifyItem(2, 730, 390., true, "Mild", true);
496+ QCOMPARE(lvwph->m_minYExtent, 250.);
497+ QCOMPARE(lvwph->m_clipItem->y(), -250.);
498+ QCOMPARE(lvwph->m_clipItem->clip(), false);
499+ QCOMPARE(lvwph->m_headerItem->y(), -250.);
500+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
501+ QCOMPARE(lvwph->contentY(), -250.);
502+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
503+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
504+ }
505+
506+ void testShowHideShowHeaderAtBottom()
507+ {
508+ scrollToBottom();
509+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
510+ QCOMPARE(lvwph->m_firstVisibleIndex, 3);
511+ verifyItem(0, -588., 390., true, "Bold", true);
512+ verifyItem(1, -198, 350., false, QString(), true);
513+ verifyItem(2, 152, 390., false, "Lazy", false);
514+ QCOMPARE(lvwph->m_minYExtent, 310.);
515+ QCOMPARE(lvwph->m_clipItem->y(), 1458.);
516+ QCOMPARE(lvwph->m_clipItem->clip(), false);
517+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
518+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
519+ QCOMPARE(lvwph->contentY(), 1458.);
520+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
521+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
522+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
523+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
524+
525+ changeContentY(-30);
526+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
527+ QCOMPARE(lvwph->m_firstVisibleIndex, 3);
528+ verifyItem(0, -588., 390., true, "Bold", true);
529+ verifyItem(1, -198, 350., false, QString(), true);
530+ verifyItem(2, 152, 390., false, "Lazy", false);
531+ QCOMPARE(lvwph->m_minYExtent, 310.);
532+ QCOMPARE(lvwph->m_clipItem->y(), 1458.);
533+ QCOMPARE(lvwph->m_clipItem->clip(), true);
534+ QCOMPARE(lvwph->m_headerItem->y(), 1408.);
535+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
536+ QCOMPARE(lvwph->contentY(), 1428.);
537+ QCOMPARE(lvwph->m_headerItemShownHeight, 30.);
538+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
539+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
540+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
541+
542+ changeContentY(30);
543+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
544+ QCOMPARE(lvwph->m_firstVisibleIndex, 3);
545+ verifyItem(0, -588., 390., true, "Bold", true);
546+ verifyItem(1, -198, 350., false, QString(), true);
547+ verifyItem(2, 152, 390., false, "Lazy", false);
548+ QCOMPARE(lvwph->m_minYExtent, 310.);
549+ QCOMPARE(lvwph->m_clipItem->y(), 1458.);
550+ QCOMPARE(lvwph->m_clipItem->clip(), false);
551+ QCOMPARE(lvwph->m_headerItem->y(), -310.);
552+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
553+ QCOMPARE(lvwph->contentY(), 1458.);
554+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
555+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
556+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
557+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
558+
559+ changeContentY(-30);
560+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
561+ QCOMPARE(lvwph->m_firstVisibleIndex, 3);
562+ verifyItem(0, -588., 390., true, "Bold", true);
563+ verifyItem(1, -198, 350., false, QString(), true);
564+ verifyItem(2, 152, 390., false, "Lazy", false);
565+ QCOMPARE(lvwph->m_minYExtent, 310.);
566+ QCOMPARE(lvwph->m_clipItem->y(), 1458.);
567+ QCOMPARE(lvwph->m_clipItem->clip(), true);
568+ QCOMPARE(lvwph->m_headerItem->y(), 1408.);
569+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
570+ QCOMPARE(lvwph->contentY(), 1428.);
571+ QCOMPARE(lvwph->m_headerItemShownHeight, 30.);
572+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
573+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
574+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
575+ }
576+
577+ void testChangeDelegateAtBottom()
578+ {
579+ scrollToBottom();
580+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
581+ QCOMPARE(lvwph->m_firstVisibleIndex, 3);
582+ verifyItem(0, -588., 390., true, "Bold", true);
583+ verifyItem(1, -198, 350., false, QString(), true);
584+ verifyItem(2, 152, 390., false, "Lazy", false);
585+ QCOMPARE(lvwph->m_minYExtent, 310.);
586+ QCOMPARE(lvwph->m_clipItem->y(), 1458.);
587+ QCOMPARE(lvwph->m_clipItem->clip(), false);
588+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
589+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
590+ QCOMPARE(lvwph->contentY(), 1458.);
591+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
592+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
593+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
594+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
595+
596+ lvwph->setDelegate(otherDelegate);
597+
598+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 6);
599+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
600+ verifyItem(0, 50., 75., false, "Agressive", false);
601+ verifyItem(1, 125, 75., false, "Regular", false);
602+ verifyItem(2, 200, 75., false, "Mild", false);
603+ verifyItem(3, 275, 75., false, "Bold", false);
604+ verifyItem(4, 350, 35., false, QString(), true);
605+ verifyItem(5, 385, 75., false, "Lazy", false);
606+ QCOMPARE(lvwph->m_minYExtent, 0.);
607+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
608+ QCOMPARE(lvwph->m_clipItem->clip(), false);
609+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
610+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
611+ QCOMPARE(lvwph->contentY(), 0.);
612+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
613+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
614+ }
615+
616+ void testSetEmptyHeaderAtTop()
617+ {
618+ lvwph->setHeader(nullptr);
619+
620+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
621+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
622+ verifyItem(0, 0., 190., false, "Agressive", false);
623+ verifyItem(1, 190., 240., false, "Regular", false);
624+ verifyItem(2, 430., 390., false, "Mild", false);
625+ QCOMPARE(lvwph->m_minYExtent, 0.);
626+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
627+ QCOMPARE(lvwph->m_clipItem->clip(), false);
628+ QCOMPARE(lvwph->m_headerItem, (QQuickItem*)nullptr);
629+ QCOMPARE(lvwph->contentY(), 0.);
630+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
631+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
632+ }
633+
634+ void testSetEmptyHeaderAtBottom()
635+ {
636+ scrollToBottom();
637+ lvwph->setHeader(nullptr);
638+
639+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
640+ QCOMPARE(lvwph->m_firstVisibleIndex, 3);
641+ verifyItem(0, -588., 390., true, "Bold", true);
642+ verifyItem(1, -198, 350., false, QString(), true);
643+ verifyItem(2, 152, 390., false, "Lazy", false);
644+ QCOMPARE(lvwph->m_minYExtent, 260.);
645+ QCOMPARE(lvwph->m_clipItem->y(), 1458.);
646+ QCOMPARE(lvwph->m_clipItem->clip(), false);
647+ QCOMPARE(lvwph->m_headerItem, (QQuickItem*)nullptr);
648+ QCOMPARE(lvwph->contentY(), 1458.);
649+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
650+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
651+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
652+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
653+
654+ scrollToTop();
655+
656+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
657+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
658+ verifyItem(0, 0., 190., false, "Agressive", false);
659+ verifyItem(1, 190., 240., false, "Regular", false);
660+ verifyItem(2, 430., 390., false, "Mild", false);
661+ QCOMPARE(lvwph->m_minYExtent, -50.);
662+ QCOMPARE(lvwph->m_clipItem->y(), 50.);
663+ QCOMPARE(lvwph->m_clipItem->clip(), false);
664+ QCOMPARE(lvwph->m_headerItem, (QQuickItem*)nullptr);
665+ QCOMPARE(lvwph->contentY(), 50.);
666+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
667+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
668+ }
669+
670+ void testSetEmptyHeaderWhenPartlyShownClipped()
671+ {
672+ scrollToBottom();
673+ changeContentY(-30);
674+ lvwph->setHeader(nullptr);
675+
676+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
677+ QCOMPARE(lvwph->m_firstVisibleIndex, 3);
678+ verifyItem(0, -588., 390., true, "Bold", true);
679+ verifyItem(1, -198, 350., false, QString(), true);
680+ verifyItem(2, 152, 390., false, "Lazy", false);
681+ QCOMPARE(lvwph->m_minYExtent, 290.);
682+ QCOMPARE(lvwph->m_clipItem->y(), 1428.);
683+ QCOMPARE(lvwph->m_clipItem->clip(), false);
684+ QCOMPARE(lvwph->m_headerItem, (QQuickItem*)nullptr);
685+ QCOMPARE(lvwph->contentY(), 1428.);
686+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
687+ QTRY_VERIFY(lvwph->isAtYEnd());
688+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
689+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
690+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
691+
692+ scrollToTop();
693+
694+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
695+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
696+ verifyItem(0, 0., 190., false, "Agressive", false);
697+ verifyItem(1, 190., 240., false, "Regular", false);
698+ verifyItem(2, 430., 390., false, "Mild", false);
699+ QCOMPARE(lvwph->m_minYExtent, -20.);
700+ QCOMPARE(lvwph->m_clipItem->y(), 20.);
701+ QCOMPARE(lvwph->m_clipItem->clip(), false);
702+ QCOMPARE(lvwph->m_headerItem, (QQuickItem*)nullptr);
703+ QCOMPARE(lvwph->contentY(), 20.);
704+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
705+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
706+ }
707+
708+ void testSetEmptyHeaderWhenPartlyShownNotClipped()
709+ {
710+ changeContentY(30);
711+ lvwph->setHeader(nullptr);
712+
713+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
714+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
715+ verifyItem(0, -30., 190., false, "Agressive", true);
716+ verifyItem(1, 160., 240., false, "Regular", false);
717+ verifyItem(2, 400., 390., false, "Mild", false);
718+ QCOMPARE(lvwph->m_minYExtent, 0.);
719+ QCOMPARE(lvwph->m_clipItem->y(), 30.);
720+ QCOMPARE(lvwph->m_clipItem->clip(), false);
721+ QCOMPARE(lvwph->m_headerItem, (QQuickItem*)nullptr);
722+ QCOMPARE(lvwph->contentY(), 30.);
723+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
724+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
725+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Agressive"));
726+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
727+ }
728+
729+ void testSetNullDelegate()
730+ {
731+ lvwph->setDelegate(nullptr);
732+
733+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 0);
734+ QCOMPARE(lvwph->m_firstVisibleIndex, -1);
735+ QCOMPARE(lvwph->m_minYExtent, 0.);
736+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
737+ QCOMPARE(lvwph->m_clipItem->clip(), false);
738+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
739+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
740+ QCOMPARE(lvwph->contentY(), 0.);
741+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
742+ QTRY_COMPARE(lvwph->contentHeight(), 50.);
743+ QVERIFY(lvwph->isAtYBeginning());
744+ QVERIFY(lvwph->isAtYEnd());
745+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
746+ }
747+
748+ void testInsertItems()
749+ {
750+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 100), Q_ARG(QVariant, "Agressive"));
751+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 125), Q_ARG(QVariant, "Regular"));
752+
753+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 5);
754+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
755+ verifyItem(0, 50., 190., false, "Agressive", false);
756+ verifyItem(1, 240., 165., false, "Regular", false);
757+ verifyItem(2, 405., 140., false, "Agressive", false);
758+ verifyItem(3, 545., 240., true, "Regular", true);
759+ verifyItem(4, 785., 390., true, "Mild", true);
760+ QCOMPARE(lvwph->m_minYExtent, 0.);
761+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
762+ QCOMPARE(lvwph->m_clipItem->clip(), false);
763+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
764+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
765+ QCOMPARE(lvwph->contentY(), 0.);
766+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
767+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
768+ }
769+
770+ void testInsertItemsStealSectionItem()
771+ {
772+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 125), Q_ARG(QVariant, "Regular"));
773+
774+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
775+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
776+ verifyItem(0, 50., 190., false, "Agressive", false);
777+ verifyItem(1, 240., 165., false, "Regular", false);
778+ verifyItem(2, 405., 200., false, QString(), true);
779+ verifyItem(3, 605., 390., true, "Mild", true);
780+ QCOMPARE(lvwph->m_minYExtent, 0.);
781+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
782+ QCOMPARE(lvwph->m_clipItem->clip(), false);
783+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
784+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
785+ QCOMPARE(lvwph->contentY(), 0.);
786+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
787+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
788+ }
789+
790+
791+ void testInsertItemsOnNotShownPosition()
792+ {
793+ changeContentY(800);
794+
795+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
796+ QTRY_COMPARE(lvwph->m_firstVisibleIndex, 2);
797+ verifyItem(0, -320., 390., false, "Mild", true);
798+ verifyItem(1, 70, 390., false, "Bold", false);
799+ verifyItem(2, 460, 350., false, QString(), false);
800+ verifyItem(3, 810, 390., true, "Lazy", true);
801+ QCOMPARE(lvwph->m_minYExtent, 330.);
802+ QCOMPARE(lvwph->m_clipItem->y(), 800.);
803+ QCOMPARE(lvwph->m_clipItem->clip(), false);
804+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
805+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
806+ QCOMPARE(lvwph->contentY(), 800.);
807+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
808+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
809+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
810+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
811+
812+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 100), Q_ARG(QVariant, "Agressive"));
813+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 125), Q_ARG(QVariant, "Regular"));
814+
815+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
816+ QCOMPARE(lvwph->m_firstVisibleIndex, 4);
817+ verifyItem(0, -320., 390., false, "Mild", true);
818+ verifyItem(1, 70, 390., false, "Bold", false);
819+ verifyItem(2, 460, 350., false, QString(), false);
820+ verifyItem(3, 810, 390., true, "Lazy", true);
821+ QCOMPARE(lvwph->m_minYExtent, 1090.);
822+ QCOMPARE(lvwph->m_clipItem->y(), 800.);
823+ QCOMPARE(lvwph->m_clipItem->clip(), false);
824+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
825+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
826+ QCOMPARE(lvwph->contentY(), 800.);
827+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
828+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
829+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
830+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
831+
832+ scrollToTop();
833+
834+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 5);
835+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
836+ verifyItem(0, 50., 190., false, "Agressive", false);
837+ verifyItem(1, 240., 165., false, "Regular", false);
838+ verifyItem(2, 405., 140., false, "Agressive", false);
839+ verifyItem(3, 545., 240., true, "Regular", true);
840+ verifyItem(4, 785., 390., true, "Mild", true);
841+ QCOMPARE(lvwph->m_minYExtent, 305.);
842+ QCOMPARE(lvwph->m_clipItem->y(), -305.);
843+ QCOMPARE(lvwph->m_clipItem->clip(), false);
844+ QCOMPARE(lvwph->m_headerItem->y(), -305.);
845+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
846+ QCOMPARE(lvwph->contentY(), -305.);
847+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
848+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
849+ }
850+
851+ void testInsertItemsAtEndOfViewport()
852+ {
853+ changeContentY(60);
854+
855+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
856+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
857+ verifyItem(0, -10., 190., false, "Agressive", true);
858+ verifyItem(1, 180., 240., false, "Regular", false);
859+ verifyItem(2, 420., 390., false, "Mild", false);
860+ verifyItem(3, 810., 390., true, "Bold", true);
861+ QCOMPARE(lvwph->m_minYExtent, 0.);
862+ QCOMPARE(lvwph->m_clipItem->y(), 60.);
863+ QCOMPARE(lvwph->m_clipItem->clip(), false);
864+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
865+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
866+ QCOMPARE(lvwph->contentY(), 60.);
867+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
868+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
869+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Agressive"));
870+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
871+
872+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 3), Q_ARG(QVariant, 100), Q_ARG(QVariant, "Agressive"));
873+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 3), Q_ARG(QVariant, 125), Q_ARG(QVariant, "Regular"));
874+
875+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
876+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
877+ verifyItem(0, -10., 190., false, "Agressive", true);
878+ verifyItem(1, 180., 240., false, "Regular", false);
879+ verifyItem(2, 420., 390., false, "Mild", false);
880+ verifyItem(3, 810., 165., true, "Regular", true);
881+ QCOMPARE(lvwph->m_minYExtent, 0.);
882+ QCOMPARE(lvwph->m_clipItem->y(), 60.);
883+ QCOMPARE(lvwph->m_clipItem->clip(), false);
884+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
885+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
886+ QCOMPARE(lvwph->contentY(), 60.);
887+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
888+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
889+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Agressive"));
890+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
891+ }
892+
893+ void testInsertItemsBeforeValidIndex()
894+ {
895+ changeContentY(520);
896+
897+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
898+ QCOMPARE(lvwph->m_firstVisibleIndex, 1);
899+ verifyItem(0, -280., 240., true, "Regular", true);
900+ verifyItem(1, -40, 390., false, "Mild", true);
901+ verifyItem(2, 350, 390., false, "Bold", false);
902+ verifyItem(3, 740, 350., true, QString(), true);
903+ QCOMPARE(lvwph->m_minYExtent, 152.5);
904+ QCOMPARE(lvwph->m_clipItem->y(), 520.);
905+ QCOMPARE(lvwph->m_clipItem->clip(), false);
906+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
907+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
908+ QCOMPARE(lvwph->contentY(), 520.);
909+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
910+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
911+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
912+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
913+
914+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 100), Q_ARG(QVariant, "Agressive"));
915+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 125), Q_ARG(QVariant, "Regular"));
916+
917+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
918+ QCOMPARE(lvwph->m_firstVisibleIndex, 3);
919+ verifyItem(0, -280., 240., true, "Regular", true);
920+ verifyItem(1, -40, 390., false, "Mild", true);
921+ verifyItem(2, 350, 390., false, "Bold", false);
922+ verifyItem(3, 740, 350., true, QString(), true);
923+ QCOMPARE(lvwph->m_minYExtent, 837.5);
924+ QCOMPARE(lvwph->m_clipItem->y(), 520.);
925+ QCOMPARE(lvwph->m_clipItem->clip(), false);
926+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
927+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
928+ QCOMPARE(lvwph->contentY(), 520.);
929+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
930+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
931+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
932+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
933+ }
934+
935+ void testInsertItemsBeforeViewport()
936+ {
937+ changeContentY(375);
938+
939+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
940+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
941+ verifyItem(0, -325., 190., true, "Agressive", true);
942+ verifyItem(1, -135, 240., false, "Regular", true);
943+ verifyItem(2, 105, 390., false, "Mild", false);
944+ verifyItem(3, 495, 390., false, "Bold", false);
945+ QCOMPARE(lvwph->m_minYExtent, 0.);
946+ QCOMPARE(lvwph->m_clipItem->y(), 375.);
947+ QCOMPARE(lvwph->m_clipItem->clip(), false);
948+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
949+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
950+ QCOMPARE(lvwph->contentY(), 375.);
951+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
952+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
953+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
954+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
955+
956+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 100), Q_ARG(QVariant, "Agressive"));
957+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 125), Q_ARG(QVariant, "Regular"));
958+
959+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
960+ QCOMPARE(lvwph->m_firstVisibleIndex, 2);
961+ verifyItem(0, -275., 140., true, "Agressive", true);
962+ verifyItem(1, -135., 240., false, "Regular", true);
963+ verifyItem(2, 105, 390., false, "Mild", false);
964+ verifyItem(3, 495, 390., false, "Bold", false);
965+ QCOMPARE(lvwph->m_minYExtent, 530.);
966+ QCOMPARE(lvwph->m_clipItem->y(), 375.);
967+ QCOMPARE(lvwph->m_clipItem->clip(), false);
968+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
969+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
970+ QCOMPARE(lvwph->contentY(), 375.);
971+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
972+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
973+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
974+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
975+
976+ scrollToTop();
977+
978+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 5);
979+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
980+ verifyItem(0, 50., 190., false, "Agressive", false);
981+ verifyItem(1, 240., 165., false, "Regular", false);
982+ verifyItem(2, 405., 140., false, "Agressive", false);
983+ verifyItem(3, 545., 240., true, "Regular", true);
984+ verifyItem(4, 785., 390., true, "Mild", true);
985+ QCOMPARE(lvwph->m_minYExtent, 305.);
986+ QCOMPARE(lvwph->m_clipItem->y(), -305.);
987+ QCOMPARE(lvwph->m_clipItem->clip(), false);
988+ QCOMPARE(lvwph->m_headerItem->y(), -305.);
989+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
990+ QCOMPARE(lvwph->contentY(), -305.);
991+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
992+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
993+ }
994+
995+ void testInsertItemsAtBottom()
996+ {
997+ scrollToBottom();
998+
999+ QVERIFY(lvwph->isAtYEnd());
1000+
1001+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 100), Q_ARG(QVariant, "Agressive"));
1002+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 125), Q_ARG(QVariant, "Regular"));
1003+
1004+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 5);
1005+ QCOMPARE(lvwph->m_firstVisibleIndex, 3);
1006+ verifyItem(0, -588., 390., true, "Bold", true);
1007+ verifyItem(1, -198, 350., false, QString(), true);
1008+ verifyItem(2, 152, 390., false, "Lazy", false);
1009+ verifyItem(3, 542, 165., true, "Regular", true);
1010+ verifyItem(4, 707, 140., true, "Agressive", true);
1011+ QCOMPARE(lvwph->m_minYExtent, 41.);
1012+ QCOMPARE(lvwph->m_clipItem->y(), 1458.);
1013+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1014+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1015+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1016+ QCOMPARE(lvwph->contentY(), 1458.);
1017+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1018+ QVERIFY(!lvwph->isAtYEnd());
1019+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1020+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
1021+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1022+
1023+ scrollToBottom();
1024+
1025+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
1026+ QCOMPARE(lvwph->m_firstVisibleIndex, 4);
1027+ verifyItem(0, -503., 350., true, QString(), true);
1028+ verifyItem(1, -153, 390., false, "Lazy", true);
1029+ verifyItem(2, 237, 165., false, "Regular", false);
1030+ verifyItem(3, 402, 140., false, "Agressive", false);
1031+ QCOMPARE(lvwph->m_minYExtent, -165.);
1032+ QCOMPARE(lvwph->m_clipItem->y(), 1763.);
1033+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1034+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1035+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1036+ QCOMPARE(lvwph->contentY(), 1763.);
1037+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1038+ QVERIFY(lvwph->isAtYEnd());
1039+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1040+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Lazy"));
1041+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1042+ }
1043+
1044+ void testInsertItemAtTop()
1045+ {
1046+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75), Q_ARG(QVariant, "Agressive"));
1047+
1048+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
1049+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1050+ verifyItem(0, 50., 115., false, "Agressive", false);
1051+ verifyItem(1, 165., 150., false, QString(), false);
1052+ verifyItem(2, 315., 240., false, "Regular", false);
1053+ verifyItem(3, 555., 390., true, "Mild", true);
1054+ QCOMPARE(lvwph->m_minYExtent, 0.);
1055+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
1056+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1057+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1058+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1059+ QCOMPARE(lvwph->contentY(), 0.);
1060+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1061+ QVERIFY(lvwph->isAtYBeginning());
1062+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1063+ }
1064+
1065+ void testInsertItem10SmallItemsAtTopWhenAtBottom()
1066+ {
1067+ scrollToBottom();
1068+
1069+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75), Q_ARG(QVariant, "Agressive"));
1070+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75), Q_ARG(QVariant, "Agressive"));
1071+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75), Q_ARG(QVariant, "Agressive"));
1072+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75), Q_ARG(QVariant, "Regular"));
1073+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75), Q_ARG(QVariant, "Regular"));
1074+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75), Q_ARG(QVariant, "Regular"));
1075+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75), Q_ARG(QVariant, "Agressive"));
1076+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75), Q_ARG(QVariant, "Agressive"));
1077+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75), Q_ARG(QVariant, "Regular"));
1078+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 75), Q_ARG(QVariant, "Agressive"));
1079+
1080+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
1081+ QCOMPARE(lvwph->m_firstVisibleIndex, 13);
1082+ verifyItem(0, -588., 390., true, "Bold", true);
1083+ verifyItem(1, -198, 350., false, QString(), true);
1084+ verifyItem(2, 152, 390., false, "Lazy", false);
1085+ QCOMPARE(lvwph->m_minYExtent, 12230./3.);
1086+ QCOMPARE(lvwph->m_clipItem->y(), 1458.);
1087+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1088+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1089+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1090+ QCOMPARE(lvwph->contentY(), 1458.);
1091+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1092+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1093+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
1094+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1095+
1096+ changeContentY(-1700);
1097+
1098+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 10);
1099+ QCOMPARE(lvwph->m_firstVisibleIndex, 3);
1100+ verifyItem(0, -323., 75., true, QString(), true);
1101+ verifyItem(1, -248., 115., true, "Regular", true);
1102+ verifyItem(2, -133., 75., true, QString(), true);
1103+ verifyItem(3, -58., 75., false, QString(), true);
1104+ verifyItem(4, 17., 115., false, "Agressive", false);
1105+ verifyItem(5, 132., 75., false, QString(), true);
1106+ verifyItem(6, 207., 75., false, QString(), true);
1107+ verifyItem(7, 282., 150., false, QString(), true);
1108+ verifyItem(8, 432., 240., false, "Regular", false);
1109+ QCOMPARE(lvwph->m_minYExtent, 980.5);
1110+ QCOMPARE(lvwph->m_clipItem->y(), -192.);
1111+ QCOMPARE(lvwph->m_clipItem->clip(), true);
1112+ QCOMPARE(lvwph->m_headerItem->y(), -242.);
1113+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1114+ QCOMPARE(lvwph->contentY(), -242.);
1115+ QCOMPARE(lvwph->m_headerItemShownHeight, 50.);
1116+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1117+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
1118+ QCOMPARE(lvwph->m_topSectionItem->y(), -23.);
1119+ }
1120+
1121+ void testRemoveItemsAtTop()
1122+ {
1123+ QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 2));
1124+
1125+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 2);
1126+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1127+ verifyItem(0, 50., 390., false, "Mild", false);
1128+ verifyItem(1, 440., 390., false, "Bold", false);
1129+ QCOMPARE(lvwph->m_minYExtent, 0.);
1130+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
1131+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1132+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1133+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1134+ QCOMPARE(lvwph->contentY(), 0.);
1135+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1136+ QVERIFY(lvwph->isAtYBeginning());
1137+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1138+ }
1139+
1140+ void testRemoveNonCreatedItemsAtTopWhenAtBottom()
1141+ {
1142+ scrollToBottom();
1143+
1144+ QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 2));
1145+
1146+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
1147+ QCOMPARE(lvwph->m_firstVisibleIndex, 1);
1148+ verifyItem(0, -588., 390., true, "Bold", true);
1149+ verifyItem(1, -198, 350., false, QString(), true);
1150+ verifyItem(2, 152, 390., false, "Lazy", false);
1151+ QCOMPARE(lvwph->m_minYExtent, -1330./3.);
1152+ QCOMPARE(lvwph->m_clipItem->y(), 1458.);
1153+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1154+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1155+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1156+ QCOMPARE(lvwph->contentY(), 1458.);
1157+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1158+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1159+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
1160+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1161+ }
1162+
1163+ void testRemoveLastItemsAtBottom()
1164+ {
1165+ scrollToBottom();
1166+
1167+ QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 4), Q_ARG(QVariant, 2));
1168+
1169+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
1170+ QCOMPARE(lvwph->m_firstVisibleIndex, 1);
1171+ verifyItem(0, -478., 240., true, "Regular", true);
1172+ verifyItem(1, -238, 390., false, "Mild", true);
1173+ verifyItem(2, 152, 390., false, "Bold", false);
1174+ QCOMPARE(lvwph->m_minYExtent, 150.);
1175+ QCOMPARE(lvwph->m_clipItem->y(), 718.);
1176+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1177+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1178+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1179+ QCOMPARE(lvwph->contentY(), 718.);
1180+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1181+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1182+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
1183+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1184+ }
1185+
1186+ void testRemoveItemOutOfViewport()
1187+ {
1188+ changeContentY(520);
1189+
1190+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
1191+ QCOMPARE(lvwph->m_firstVisibleIndex, 1);
1192+ verifyItem(0, -280., 240., true, "Regular", true);
1193+ verifyItem(1, -40, 390., false, "Mild", true);
1194+ verifyItem(2, 350, 390., false, "Bold", false);
1195+ verifyItem(3, 740, 350., true, QString(), true);
1196+ QCOMPARE(lvwph->m_minYExtent, 152.5);
1197+ QCOMPARE(lvwph->m_clipItem->y(), 520.);
1198+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1199+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1200+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1201+ QCOMPARE(lvwph->contentY(), 520.);
1202+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1203+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1204+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
1205+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1206+
1207+ QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 1), Q_ARG(QVariant, 1));
1208+
1209+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
1210+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1211+ verifyItem(0, -230., 190., true, "Agressive", true);
1212+ verifyItem(1, -40, 390., false, "Mild", true);
1213+ verifyItem(2, 350, 390., false, "Bold", false);
1214+ verifyItem(3, 740, 350., true, QString(), true);
1215+ QCOMPARE(lvwph->m_minYExtent, -240.);
1216+ QCOMPARE(lvwph->m_clipItem->y(), 520.);
1217+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1218+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1219+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1220+ QCOMPARE(lvwph->contentY(), 520.);
1221+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1222+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1223+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
1224+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1225+ }
1226+
1227+ void testRemoveFirstOfCategory()
1228+ {
1229+ changeContentY(520);
1230+
1231+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
1232+ QCOMPARE(lvwph->m_firstVisibleIndex, 1);
1233+ verifyItem(0, -280., 240., true, "Regular", true);
1234+ verifyItem(1, -40, 390., false, "Mild", true);
1235+ verifyItem(2, 350, 390., false, "Bold", false);
1236+ verifyItem(3, 740, 350., true, QString(), true);
1237+ QCOMPARE(lvwph->m_minYExtent, 152.5);
1238+ QCOMPARE(lvwph->m_clipItem->y(), 520.);
1239+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1240+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1241+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1242+ QCOMPARE(lvwph->contentY(), 520.);
1243+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1244+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1245+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
1246+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1247+
1248+ QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 3), Q_ARG(QVariant, 1));
1249+
1250+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
1251+ QCOMPARE(lvwph->m_firstVisibleIndex, 1);
1252+ verifyItem(0, -280., 240., true, "Regular", true);
1253+ verifyItem(1, -40, 390., false, "Mild", true);
1254+ verifyItem(2, 350, 390., false, "Bold", false);
1255+ verifyItem(3, 740, 390., true, "Lazy", true);
1256+ QCOMPARE(lvwph->m_minYExtent, 162.5);
1257+ QCOMPARE(lvwph->m_clipItem->y(), 520.);
1258+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1259+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1260+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1261+ QCOMPARE(lvwph->contentY(), 520.);
1262+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1263+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1264+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
1265+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1266+ }
1267+
1268+ void testAddSecondToCulledCategoryOfTwo()
1269+ {
1270+ // Do some setup
1271+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 25), Q_ARG(QVariant, "Agressive"));
1272+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 25), Q_ARG(QVariant, "Agressive"));
1273+
1274+ changeContentY(200);
1275+
1276+ // Very the items are culled
1277+ verifyItem(0, -150., 65., true, "Agressive", true);
1278+ verifyItem(1, -85, 25., true, QString(), true);
1279+
1280+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 25), Q_ARG(QVariant, "Agressive"));
1281+
1282+ // Very the new item is there correctly
1283+ verifyItem(0, -175., 65., true, "Agressive", true);
1284+ verifyItem(1, -110, 25., true, QString(), true);
1285+ verifyItem(2, -85, 25., true, QString(), true);
1286+ }
1287+
1288+ void testMoveFirstItems()
1289+ {
1290+ QMetaObject::invokeMethod(model, "moveItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 1), Q_ARG(QVariant, 1));
1291+
1292+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
1293+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1294+ verifyItem(0, 50., 240., false, "Regular", false);
1295+ verifyItem(1, 290., 190., false, "Agressive", false);
1296+ verifyItem(2, 480., 390., false, "Mild", false);
1297+ QCOMPARE(lvwph->m_minYExtent, 0.);
1298+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
1299+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1300+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1301+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1302+ QCOMPARE(lvwph->contentY(), 0.);
1303+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1304+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1305+ }
1306+
1307+ void testMoveFirstOutOfVisibleItems()
1308+ {
1309+ QMetaObject::invokeMethod(model, "moveItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 4), Q_ARG(QVariant, 1));
1310+
1311+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
1312+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1313+ verifyItem(0, 50., 240., false, "Regular", false);
1314+ verifyItem(1, 290., 390., false, "Mild", false);
1315+ verifyItem(2, 680., 390., true, "Bold", true);
1316+ QCOMPARE(lvwph->m_minYExtent, 0.);
1317+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
1318+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1319+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1320+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1321+ QCOMPARE(lvwph->contentY(), 0.);
1322+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1323+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1324+ }
1325+
1326+ void testMoveFirstToLastAtBottom()
1327+ {
1328+ scrollToBottom();
1329+
1330+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
1331+ QCOMPARE(lvwph->m_firstVisibleIndex, 3);
1332+ verifyItem(0, -588., 390., true, "Bold", true);
1333+ verifyItem(1, -198, 350., false, QString(), true);
1334+ verifyItem(2, 152, 390., false, "Lazy", false);
1335+ QCOMPARE(lvwph->m_minYExtent, 310.);
1336+ QCOMPARE(lvwph->m_clipItem->y(), 1458.);
1337+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1338+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1339+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1340+ QCOMPARE(lvwph->contentY(), 1458.);
1341+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1342+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1343+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
1344+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1345+
1346+ QMetaObject::invokeMethod(model, "moveItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 5), Q_ARG(QVariant, 1));
1347+
1348+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
1349+ QCOMPARE(lvwph->m_firstVisibleIndex, 2);
1350+ verifyItem(0, -588., 390., true, "Bold", true);
1351+ verifyItem(1, -198, 350., false, QString(), true);
1352+ verifyItem(2, 152, 390., false, "Lazy", false);
1353+ verifyItem(3, 542, 190., true, "Agressive", true);
1354+ QCOMPARE(lvwph->m_minYExtent, -160.);
1355+ QCOMPARE(lvwph->m_clipItem->y(), 1458.);
1356+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1357+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1358+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1359+ QCOMPARE(lvwph->contentY(), 1458.);
1360+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1361+ QVERIFY(!lvwph->isAtYEnd());
1362+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1363+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
1364+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1365+ }
1366+
1367+ void testChangeSizeVisibleItemNotOnViewport()
1368+ {
1369+ changeContentY(490);
1370+
1371+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 5);
1372+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1373+ verifyItem(0, -440., 190., true, "Agressive", true);
1374+ verifyItem(1, -250., 240., true, "Regular", true);
1375+ verifyItem(2, -10, 390., false, "Mild", true);
1376+ verifyItem(3, 380, 390., false, "Bold", false);
1377+ verifyItem(4, 770, 350., true, QString(), true);
1378+ QCOMPARE(lvwph->m_minYExtent, 0.);
1379+ QCOMPARE(lvwph->m_clipItem->y(), 490.);
1380+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1381+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1382+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1383+ QCOMPARE(lvwph->contentY(), 490.);
1384+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1385+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1386+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
1387+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1388+
1389+ model->setProperty(1, "size", 100);
1390+
1391+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 5);
1392+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1393+ verifyItem(0, -340., 190., true, "Agressive", true);
1394+ verifyItem(1, -150., 140., true, "Regular", true);
1395+ verifyItem(2, -10, 390., false, "Mild", true);
1396+ verifyItem(3, 380, 390., false, "Bold", false);
1397+ verifyItem(4, 770, 350., true, QString(), true);
1398+ QCOMPARE(lvwph->m_minYExtent, -100.);
1399+ QCOMPARE(lvwph->m_clipItem->y(), 490.);
1400+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1401+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1402+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1403+ QCOMPARE(lvwph->contentY(), 490.);
1404+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1405+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1406+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
1407+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1408+ }
1409+
1410+ void testShowHeaderCloseToTheTop()
1411+ {
1412+ changeContentY(375);
1413+
1414+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
1415+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1416+ verifyItem(0, -325., 190., true, "Agressive", true);
1417+ verifyItem(1, -135, 240., false, "Regular", true);
1418+ verifyItem(2, 105, 390., false, "Mild", false);
1419+ verifyItem(3, 495, 390., false, "Bold", false);
1420+ QCOMPARE(lvwph->m_minYExtent, 0.);
1421+ QCOMPARE(lvwph->m_clipItem->y(), 375.);
1422+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1423+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1424+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1425+ QCOMPARE(lvwph->contentY(), 375.);
1426+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);;
1427+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1428+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
1429+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1430+
1431+ lvwph->showHeader();
1432+
1433+ QTRY_VERIFY(!lvwph->m_headerShowAnimation->isRunning());
1434+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
1435+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1436+ verifyItem(0, -375., 190., true, "Agressive", true);
1437+ verifyItem(1, -185, 240., false, "Regular", true);
1438+ verifyItem(2, 55, 390., false, "Mild", false);
1439+ verifyItem(3, 445, 390., false, "Bold", false);
1440+ QCOMPARE(lvwph->m_minYExtent, 50.);
1441+ QCOMPARE(lvwph->m_clipItem->y(), 375.);
1442+ QCOMPARE(lvwph->m_clipItem->clip(), true);
1443+ QCOMPARE(lvwph->m_headerItem->y(), 325.);
1444+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1445+ QCOMPARE(lvwph->contentY(), 325.);
1446+ QCOMPARE(lvwph->m_headerItemShownHeight, 50.);
1447+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1448+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
1449+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1450+
1451+ scrollToTop();
1452+
1453+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
1454+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1455+ verifyItem(0, 50., 190., false, "Agressive", false);
1456+ verifyItem(1, 240., 240., false, "Regular", false);
1457+ verifyItem(2, 480., 390., false, "Mild", false);
1458+ QCOMPARE(lvwph->m_minYExtent, 50.);
1459+ QCOMPARE(lvwph->m_clipItem->y(), -50.);
1460+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1461+ QCOMPARE(lvwph->m_headerItem->y(), -50.);
1462+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1463+ QCOMPARE(lvwph->contentY(), -50.);
1464+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1465+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1466+ }
1467+
1468+ void testShowHeaderAtBottom()
1469+ {
1470+ scrollToBottom();
1471+
1472+ lvwph->showHeader();
1473+
1474+ QTRY_VERIFY(!lvwph->m_headerShowAnimation->isRunning());
1475+ QTRY_VERIFY (lvwph->isAtYEnd());
1476+ }
1477+
1478+ void growWindow()
1479+ {
1480+ view->rootObject()->setHeight(850);
1481+
1482+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 5);
1483+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1484+ verifyItem(0, 50., 190., false, "Agressive", false);
1485+ verifyItem(1, 240., 240., false, "Regular", false);
1486+ verifyItem(2, 480., 390., false, "Mild", false);
1487+ verifyItem(3, 870., 390., true, "Bold", true);
1488+ verifyItem(4, 1260., 350., true, QString(), true);
1489+ QCOMPARE(lvwph->m_minYExtent, 0.);
1490+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
1491+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1492+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1493+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1494+ QCOMPARE(lvwph->contentY(), 0.);
1495+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1496+ }
1497+
1498+ void growWindowAtBottom()
1499+ {
1500+ // Need a bunch small items at the bottom to trigger the problem
1501+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive"));
1502+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive"));
1503+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive"));
1504+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive"));
1505+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive"));
1506+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive"));
1507+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Regular"));
1508+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Regular"));
1509+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Regular"));
1510+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Regular"));
1511+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Regular"));
1512+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Regular"));
1513+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive"));
1514+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive"));
1515+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive"));
1516+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive"));
1517+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive"));
1518+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive"));
1519+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive"));
1520+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 6), Q_ARG(QVariant, 50), Q_ARG(QVariant, "Agressive"));
1521+
1522+ scrollToBottom();
1523+
1524+ view->rootObject()->setHeight(850);
1525+
1526+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 21);
1527+ QCOMPARE(lvwph->m_firstVisibleIndex, 5);
1528+ verifyItem(0, -660., 390., true, "Lazy", true);
1529+ verifyItem(1, -270., 90., true, "Agressive", true);
1530+ verifyItem(2, -180, 50., true, QString(), true);
1531+ verifyItem(3, -130, 50., true, QString(), true);
1532+ verifyItem(4, -80, 50., true, QString(), true);
1533+ verifyItem(5, -30, 50., false, QString(), true);
1534+ verifyItem(6, 20, 50., false, QString(), true);
1535+ verifyItem(7, 70, 50., false, QString(), true);
1536+ verifyItem(8, 120, 50., false, QString(), true);
1537+ verifyItem(9, 170, 90., false, "Regular", false);
1538+ verifyItem(10, 260, 50., false, QString(), true);
1539+ verifyItem(11, 310, 50., false, QString(), true);
1540+ verifyItem(12, 360, 50., false, QString(), true);
1541+ verifyItem(13, 410, 50., false, QString(), true);
1542+ verifyItem(14, 460, 50., false, QString(), true);
1543+ verifyItem(15, 510, 90., false, "Agressive", false);
1544+ verifyItem(16, 600, 50., false, QString(), true);
1545+ verifyItem(17, 650, 50., false, QString(), true);
1546+ verifyItem(18, 700, 50., false, QString(), true);
1547+ verifyItem(19, 750, 50., false, QString(), true);
1548+ verifyItem(20, 800, 50., false, QString(), true);
1549+ QCOMPARE(lvwph->m_minYExtent, 5 * 1510./21. + 660 - 1970 + 50);
1550+ QCOMPARE(lvwph->m_clipItem->y(), 1970.);
1551+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1552+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1553+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1554+ QCOMPARE(lvwph->contentY(), 1970.);
1555+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1556+ }
1557+
1558+private:
1559+ QQuickView *view;
1560+ ListViewWithPageHeader *lvwph;
1561+ QQuickListModel *model;
1562+ QQmlComponent *otherDelegate;
1563+};
1564+
1565+QTEST_MAIN(ListViewWithPageHeaderTestSection)
1566+
1567+#include "listviewwithpageheadertestsection.moc"
tests/plugins/ListViewWithPageHeader/test.qmlnew 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+
17+import QtQuick 2.0
18+import ListViewWithPageHeader 0.1
19+
20+Rectangle {
21+ width: 300
22+ height: 542
23+ color: "lightblue"
24+
25+ ListModel {
26+ id: model
27+
28+ function insertItem(index, size) {
29+ insert(index, { size: size });
30+ }
31+
32+ function removeItems(index, count) {
33+ remove(index, count);
34+ }
35+
36+ function moveItems(indexFrom, indexTo, count) {
37+ move(indexFrom, indexTo, count);
38+ }
39+
40+ ListElement { size: 150 }
41+ ListElement { size: 200 }
42+ ListElement { size: 350 }
43+ ListElement { size: 350 }
44+ ListElement { size: 350 }
45+ ListElement { size: 350 }
46+ }
47+
48+ Component {
49+ id: otherRect
50+ Rectangle {
51+ height: 35
52+ width: parent.width
53+ color: index % 2 == 0 ? "yellow" : "purple"
54+ }
55+ }
56+
57+ ListViewWithPageHeader {
58+ id: listView
59+ width: parent.width
60+ anchors.top: parent.top
61+ anchors.bottom: parent.bottom
62+ model: model
63+ delegate: Rectangle {
64+ property bool timerDone: false
65+ width: parent.width - 20
66+ x: 10
67+ color: index % 2 == 0 ? "red" : "blue"
68+ height: timerDone ? size : 350
69+ Text {
70+ text: index
71+ }
72+ Timer {
73+ id: sizeTimer
74+ interval: 10;
75+ onTriggered: {
76+ timerDone = true
77+ }
78+ }
79+ Component.onCompleted: {
80+ sizeTimer.start()
81+ }
82+ }
83+
84+ pageHeader: Rectangle {
85+ color: "transparent"
86+ width: parent.width
87+ height: 50
88+ implicitHeight: 50
89+ Text {
90+ anchors.fill: parent
91+ text: "APPS"
92+ font.pixelSize: 40
93+ }
94+ }
95+ }
96+}
tests/plugins/ListViewWithPageHeader/test_section.qmlnew file+106
@@ -0,0 +1,106 @@
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 ListViewWithPageHeader 0.1
19+
20+Rectangle {
21+ width: 300
22+ height: 542
23+ color: "lightblue"
24+
25+ ListModel {
26+ id: model
27+
28+ function insertItem(index, size, type) {
29+ insert(index, { size: size, type: type });
30+ }
31+
32+ function removeItems(index, count) {
33+ remove(index, count);
34+ }
35+
36+ function moveItems(indexFrom, indexTo, count) {
37+ move(indexFrom, indexTo, count);
38+ }
39+
40+ ListElement { type: "Agressive"; size: 150 }
41+ ListElement { type: "Regular"; size: 200 }
42+ ListElement { type: "Mild"; size: 350 }
43+ ListElement { type: "Bold"; size: 350 }
44+ ListElement { type: "Bold"; size: 350 }
45+ ListElement { type: "Lazy"; size: 350 }
46+ }
47+
48+ Component {
49+ id: otherRect
50+ Rectangle {
51+ height: 35
52+ width: parent.width
53+ color: index % 2 == 0 ? "yellow" : "purple"
54+ }
55+ }
56+
57+ ListViewWithPageHeader {
58+ id: listView
59+ width: parent.width
60+ anchors.top: parent.top
61+ anchors.bottom: parent.bottom
62+ model: model
63+ delegate: Rectangle {
64+ property bool timerDone: false
65+ width: parent.width - 20
66+ x: 10
67+ color: index % 2 == 0 ? "red" : "blue"
68+ height: timerDone ? size : 350
69+ Text {
70+ text: index
71+ }
72+ Timer {
73+ id: sizeTimer
74+ interval: 10;
75+ onTriggered: {
76+ timerDone = true
77+ }
78+ }
79+ Component.onCompleted: {
80+ sizeTimer.start()
81+ }
82+ }
83+
84+ pageHeader: Rectangle {
85+ color: "transparent"
86+ width: parent.width
87+ height: 50
88+ implicitHeight: 50
89+ Text {
90+ anchors.fill: parent
91+ text: "APPS"
92+ font.pixelSize: 40
93+ }
94+ }
95+
96+ sectionProperty: "type"
97+ sectionDelegate: Component {
98+ Rectangle {
99+ color: "green"
100+ height: 40
101+ Text { text: section; font.pixelSize: 34 }
102+ anchors { left: parent.left; right: parent.right }
103+ }
104+ }
105+ }
106+}
tests/plugins/Ubuntu/Gestures/tst_AxisVelocityCalculator.cpp+40−28
@@ -20,7 +20,7 @@
20
20
21#include <AxisVelocityCalculator.h>
21#include <AxisVelocityCalculator.h>
22
22
23−class FakeTimeSource : public AxisVelocityCalculator::TimeSource {
23+class FakeTimeSource : public UbuntuGestures::TimeSource {
24public:
24public:
25 FakeTimeSource() : m_value(0) {}
25 FakeTimeSource() : m_value(0) {}
26
26
@@ -44,71 +44,85 @@ class tst_AxisVelocityCalculator : public QObject
44{
44{
45 Q_OBJECT
45 Q_OBJECT
46private Q_SLOTS:
46private Q_SLOTS:
47+ void init(); // called right before each and every test function is executed
48+ void cleanup(); // called right after each and every test function is executed
49+
47 void simpleSamples();
50 void simpleSamples();
48 void noSamples();
51 void noSamples();
49 void overflowSamples();
52 void overflowSamples();
50 void average();
53 void average();
54+
55+private:
56+ AxisVelocityCalculator *velCalc;
57+ FakeTimeSource *fakeTimeSource;
51};
58};
52
59
60+void tst_AxisVelocityCalculator::init()
61+{
62+ fakeTimeSource = new FakeTimeSource;
63+
64+ velCalc = new AxisVelocityCalculator;
65+ velCalc->setTimeSource(fakeTimeSource);
66+}
67+
68+void tst_AxisVelocityCalculator::cleanup()
69+{
70+ delete velCalc;
71+ delete fakeTimeSource;
72+}
73+
53void tst_AxisVelocityCalculator::simpleSamples()
74void tst_AxisVelocityCalculator::simpleSamples()
54{
75{
55− FakeTimeSource *fakeTimeSource = new FakeTimeSource;
56− AxisVelocityCalculator velCalc(fakeTimeSource);
57 qreal pos = 0;
76 qreal pos = 0;
58
77
59− velCalc.setTrackedPosition(pos);
78+ velCalc->setTrackedPosition(pos);
60− velCalc.reset();
79+ velCalc->reset();
61
80
62 fakeTimeSource->setMsecsSinceReference(10);
81 fakeTimeSource->setMsecsSinceReference(10);
63 pos += 20;
82 pos += 20;
64− velCalc.setTrackedPosition(pos);
83+ velCalc->setTrackedPosition(pos);
65
84
66 fakeTimeSource->setMsecsSinceReference(20);
85 fakeTimeSource->setMsecsSinceReference(20);
67 pos += 20;
86 pos += 20;
68− velCalc.setTrackedPosition(pos);
87+ velCalc->setTrackedPosition(pos);
69
88
70 fakeTimeSource->setMsecsSinceReference(30);
89 fakeTimeSource->setMsecsSinceReference(30);
71 pos += 20;
90 pos += 20;
72− velCalc.setTrackedPosition(pos);
91+ velCalc->setTrackedPosition(pos);
73
92
74− qreal velocity = velCalc.calculate();
93+ qreal velocity = velCalc->calculate();
75
94
76 QCOMPARE(velocity, 2.0f);
95 QCOMPARE(velocity, 2.0f);
77}
96}
78
97
79void tst_AxisVelocityCalculator::noSamples()
98void tst_AxisVelocityCalculator::noSamples()
80{
99{
81− FakeTimeSource *fakeTimeSource = new FakeTimeSource;
82− AxisVelocityCalculator velCalc(fakeTimeSource);
83−
84− float velocity = velCalc.calculate();
100+ float velocity = velCalc->calculate();
85
101
86 QCOMPARE(velocity, 0.0f);
102 QCOMPARE(velocity, 0.0f);
87}
103}
88
104
89void tst_AxisVelocityCalculator::overflowSamples()
105void tst_AxisVelocityCalculator::overflowSamples()
90{
106{
91− FakeTimeSource *fakeTimeSource = new FakeTimeSource;
92− AxisVelocityCalculator velCalc(fakeTimeSource);
93 qreal pos = 0;
107 qreal pos = 0;
94
108
95− velCalc.setTrackedPosition(pos);
109+ velCalc->setTrackedPosition(pos);
96− velCalc.reset();
110+ velCalc->reset();
97
111
98 for (int i = 0; i < 1000; ++i) {
112 for (int i = 0; i < 1000; ++i) {
99 fakeTimeSource->increaseMsecsSinceReference(10);
113 fakeTimeSource->increaseMsecsSinceReference(10);
100 pos += 20;
114 pos += 20;
101− velCalc.setTrackedPosition(pos);
115+ velCalc->setTrackedPosition(pos);
102 }
116 }
103
117
104 /* overwrite all existing samples with faster ones */
118 /* overwrite all existing samples with faster ones */
105 for (int i = 0; i < AxisVelocityCalculator::MAX_SAMPLES; ++i) {
119 for (int i = 0; i < AxisVelocityCalculator::MAX_SAMPLES; ++i) {
106 fakeTimeSource->increaseMsecsSinceReference(10);
120 fakeTimeSource->increaseMsecsSinceReference(10);
107 pos += 40;
121 pos += 40;
108− velCalc.setTrackedPosition(pos);
122+ velCalc->setTrackedPosition(pos);
109 }
123 }
110
124
111− float velocity = velCalc.calculate();
125+ float velocity = velCalc->calculate();
112
126
113 /* check that the calculated velocity correspond to the latest, faster, samples */
127 /* check that the calculated velocity correspond to the latest, faster, samples */
114 QCOMPARE(velocity, 4.0f);
128 QCOMPARE(velocity, 4.0f);
@@ -116,28 +130,26 @@ void tst_AxisVelocityCalculator::overflowSamples()
116
130
117void tst_AxisVelocityCalculator::average()
131void tst_AxisVelocityCalculator::average()
118{
132{
119− FakeTimeSource *fakeTimeSource = new FakeTimeSource;
120− AxisVelocityCalculator velCalc(fakeTimeSource);
121 qreal pos = 0;
133 qreal pos = 0;
122
134
123− velCalc.setTrackedPosition(pos);
135+ velCalc->setTrackedPosition(pos);
124− velCalc.reset();
136+ velCalc->reset();
125
137
126 fakeTimeSource->increaseMsecsSinceReference(10);
138 fakeTimeSource->increaseMsecsSinceReference(10);
127 pos += 20;
139 pos += 20;
128− velCalc.setTrackedPosition(pos);
140+ velCalc->setTrackedPosition(pos);
129
141
130 fakeTimeSource->increaseMsecsSinceReference(10);
142 fakeTimeSource->increaseMsecsSinceReference(10);
131 pos += 20;
143 pos += 20;
132− velCalc.setTrackedPosition(pos);
144+ velCalc->setTrackedPosition(pos);
133
145
134 /* the last sample is an erratic one and would yield a big velocity if
146 /* the last sample is an erratic one and would yield a big velocity if
135 considered isolatedly */
147 considered isolatedly */
136 fakeTimeSource->increaseMsecsSinceReference(10);
148 fakeTimeSource->increaseMsecsSinceReference(10);
137 pos += 100;
149 pos += 100;
138− velCalc.setTrackedPosition(pos);
150+ velCalc->setTrackedPosition(pos);
139
151
140− float velocity = velCalc.calculate();
152+ float velocity = velCalc->calculate();
141
153
142 /* calculated velocity is lower than the one from the last sample */
154 /* calculated velocity is lower than the one from the last sample */
143 QVERIFY(velocity < 9.0f);
155 QVERIFY(velocity < 9.0f);
tests/plugins/Ubuntu/Gestures/tst_DirectionalDragArea.cpp+99−11
@@ -38,7 +38,7 @@ private:
38 int m_duration;
38 int m_duration;
39};
39};
40
40
41−class FakeTimeSource : public AxisVelocityCalculator::TimeSource
41+class FakeTimeSource : public UbuntuGestures::TimeSource
42{
42{
43public:
43public:
44 FakeTimeSource() { m_msecsSinceReference = 0; }
44 FakeTimeSource() { m_msecsSinceReference = 0; }
@@ -65,6 +65,9 @@ private Q_SLOTS:
65 void minSpeed_data();
65 void minSpeed_data();
66 void recognitionTimerUsage();
66 void recognitionTimerUsage();
67 void maxSilenceTime();
67 void maxSilenceTime();
68+ void sceneXAndX();
69+ void sceneYAndY();
70+ void emitDraggingChangedOnDirectRecognition();
68
71
69private:
72private:
70 QQuickView *createView();
73 QQuickView *createView();
@@ -72,7 +75,6 @@ private:
72 QTouchDevice *device;
75 QTouchDevice *device;
73 FakeTimer *fakeTimer;
76 FakeTimer *fakeTimer;
74 FakeTimeSource *fakeTimeSource;
77 FakeTimeSource *fakeTimeSource;
75− AxisVelocityCalculator *velCalcWithFakeTiming;
76};
78};
77
79
78void tst_DirectionalDragArea::initTestCase()
80void tst_DirectionalDragArea::initTestCase()
@@ -101,7 +103,6 @@ void tst_DirectionalDragArea::init()
101
103
102 fakeTimer = new FakeTimer;
104 fakeTimer = new FakeTimer;
103 fakeTimeSource = new FakeTimeSource;
105 fakeTimeSource = new FakeTimeSource;
104− velCalcWithFakeTiming = new AxisVelocityCalculator(fakeTimeSource);
105}
106}
106
107
107void tst_DirectionalDragArea::cleanup()
108void tst_DirectionalDragArea::cleanup()
@@ -112,10 +113,8 @@ void tst_DirectionalDragArea::cleanup()
112 delete fakeTimer;
113 delete fakeTimer;
113 fakeTimer = 0;
114 fakeTimer = 0;
114
115
115− // will bring fakeTimeSource down with it
116+ delete fakeTimeSource;
116− delete velCalcWithFakeTiming;
117 fakeTimeSource = 0;
117 fakeTimeSource = 0;
118− velCalcWithFakeTiming = 0;
119}
118}
120
119
121QQuickView *tst_DirectionalDragArea::createView()
120QQuickView *tst_DirectionalDragArea::createView()
@@ -187,7 +186,7 @@ void tst_DirectionalDragArea::edgeDrag()
187 view->rootObject()->findChild<DirectionalDragArea*>(dragAreaObjectName);
186 view->rootObject()->findChild<DirectionalDragArea*>(dragAreaObjectName);
188 QVERIFY(edgeDragArea != 0);
187 QVERIFY(edgeDragArea != 0);
189 edgeDragArea->setRecognitionTimer(fakeTimer);
188 edgeDragArea->setRecognitionTimer(fakeTimer);
190− edgeDragArea->setAxisVelocityCalculator(velCalcWithFakeTiming);
189+ edgeDragArea->setTimeSource(fakeTimeSource);
191
190
192 QSignalSpy draggingSpy(edgeDragArea, SIGNAL(draggingChanged(bool)));
191 QSignalSpy draggingSpy(edgeDragArea, SIGNAL(draggingChanged(bool)));
193
192
@@ -292,7 +291,7 @@ void tst_DirectionalDragArea::dragWithShortDirectionChange()
292 view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
291 view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
293 QVERIFY(edgeDragArea != 0);
292 QVERIFY(edgeDragArea != 0);
294 edgeDragArea->setRecognitionTimer(fakeTimer);
293 edgeDragArea->setRecognitionTimer(fakeTimer);
295− edgeDragArea->setAxisVelocityCalculator(velCalcWithFakeTiming);
294+ edgeDragArea->setTimeSource(fakeTimeSource);
296
295
297 QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, view);
296 QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, view);
298 QPointF touchPoint = initialTouchPos;
297 QPointF touchPoint = initialTouchPos;
@@ -337,7 +336,7 @@ void tst_DirectionalDragArea::minSpeed()
337 view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
336 view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
338 QVERIFY(edgeDragArea != 0);
337 QVERIFY(edgeDragArea != 0);
339 edgeDragArea->setRecognitionTimer(fakeTimer);
338 edgeDragArea->setRecognitionTimer(fakeTimer);
340− edgeDragArea->setAxisVelocityCalculator(velCalcWithFakeTiming);
339+ edgeDragArea->setTimeSource(fakeTimeSource);
341
340
342 QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, view);
341 QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, view);
343 QPointF touchPoint = initialTouchPos;
342 QPointF touchPoint = initialTouchPos;
@@ -390,7 +389,7 @@ void tst_DirectionalDragArea::recognitionTimerUsage()
390 view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
389 view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
391 QVERIFY(edgeDragArea != 0);
390 QVERIFY(edgeDragArea != 0);
392 edgeDragArea->setRecognitionTimer(fakeTimer);
391 edgeDragArea->setRecognitionTimer(fakeTimer);
393− edgeDragArea->setAxisVelocityCalculator(velCalcWithFakeTiming);
392+ edgeDragArea->setTimeSource(fakeTimeSource);
394
393
395 QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, view);
394 QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, view);
396 QPointF touchPoint = initialTouchPos;
395 QPointF touchPoint = initialTouchPos;
@@ -431,7 +430,7 @@ void tst_DirectionalDragArea::maxSilenceTime()
431 view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
430 view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
432 QVERIFY(edgeDragArea != 0);
431 QVERIFY(edgeDragArea != 0);
433 edgeDragArea->setRecognitionTimer(fakeTimer);
432 edgeDragArea->setRecognitionTimer(fakeTimer);
434− edgeDragArea->setAxisVelocityCalculator(velCalcWithFakeTiming);
433+ edgeDragArea->setTimeSource(fakeTimeSource);
435
434
436 QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, view);
435 QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, view);
437 QPointF touchPoint = initialTouchPos;
436 QPointF touchPoint = initialTouchPos;
@@ -458,6 +457,95 @@ void tst_DirectionalDragArea::maxSilenceTime()
458 QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Rejected);
457 QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Rejected);
459}
458}
460
459
460+/*
461+ Checks that it informs the X coordinate of the touch point in local and scene coordinates
462+ correctly.
463+ */
464+void tst_DirectionalDragArea::sceneXAndX()
465+{
466+ DirectionalDragArea *edgeDragArea =
467+ view->rootObject()->findChild<DirectionalDragArea*>("hnDragArea");
468+ QVERIFY(edgeDragArea != 0);
469+ edgeDragArea->setRecognitionTimer(fakeTimer);
470+ edgeDragArea->setTimeSource(fakeTimeSource);
471+
472+ QPointF touchScenePos(view->width() - (edgeDragArea->width()/2.0f), view->height()/2.0f);
473+
474+ fakeTimeSource->m_msecsSinceReference = 0;
475+ QTest::touchEvent(view, device).press(0, touchScenePos.toPoint());
476+
477+ QSignalSpy touchXSpy(edgeDragArea, SIGNAL(touchXChanged(qreal)));
478+ QSignalSpy touchSceneXSpy(edgeDragArea, SIGNAL(touchSceneXChanged(qreal)));
479+
480+ touchScenePos.rx() = view->width() / 2;
481+ QTest::touchEvent(view, device).move(0, touchScenePos.toPoint());
482+
483+ QCOMPARE(touchXSpy.count(), 1);
484+ QCOMPARE(touchSceneXSpy.count(), 1);
485+ QCOMPARE(edgeDragArea->touchX(), touchScenePos.x() - edgeDragArea->x());
486+ QCOMPARE(edgeDragArea->touchSceneX(), touchScenePos.x());
487+}
488+
489+/*
490+ Checks that it informs the Y coordinate of the touch point in local and scene coordinates
491+ correctly.
492+ */
493+void tst_DirectionalDragArea::sceneYAndY()
494+{
495+ DirectionalDragArea *edgeDragArea =
496+ view->rootObject()->findChild<DirectionalDragArea*>("vnDragArea");
497+ QVERIFY(edgeDragArea != 0);
498+ edgeDragArea->setRecognitionTimer(fakeTimer);
499+ edgeDragArea->setTimeSource(fakeTimeSource);
500+
501+ QPointF touchScenePos(view->width()/2.0f, view->height() - (edgeDragArea->height()/2.0f));
502+
503+ fakeTimeSource->m_msecsSinceReference = 0;
504+ QTest::touchEvent(view, device).press(0, touchScenePos.toPoint());
505+
506+ QSignalSpy touchYSpy(edgeDragArea, SIGNAL(touchYChanged(qreal)));
507+ QSignalSpy touchSceneYSpy(edgeDragArea, SIGNAL(touchSceneYChanged(qreal)));
508+
509+ touchScenePos.ry() = view->height() / 2;
510+ QTest::touchEvent(view, device).move(0, touchScenePos.toPoint());
511+
512+ QCOMPARE(touchYSpy.count(), 1);
513+ QCOMPARE(touchSceneYSpy.count(), 1);
514+ QCOMPARE(edgeDragArea->touchY(), touchScenePos.y() - edgeDragArea->y());
515+ QCOMPARE(edgeDragArea->touchSceneY(), touchScenePos.y());
516+}
517+
518+/*
519+ Emit draggingChanged() when status change from WaitingForTouch directly to Recognized.
520+ This happens when the gesture recognition is effectively disabled (e.g. by setting a
521+ distanceThreshold of zero)
522+ */
523+void tst_DirectionalDragArea::emitDraggingChangedOnDirectRecognition()
524+{
525+ DirectionalDragArea *edgeDragArea =
526+ view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
527+ QVERIFY(edgeDragArea != 0);
528+ edgeDragArea->setRecognitionTimer(fakeTimer);
529+ edgeDragArea->setTimeSource(fakeTimeSource);
530+
531+ QPointF touchPos = calculateInitialTouchPos(edgeDragArea, view);
532+
533+ QSignalSpy draggingSpy(edgeDragArea, SIGNAL(draggingChanged(bool)));
534+
535+ // That will make it completetly skip the recognition phase ("Undecided" status).
536+ edgeDragArea->setDistanceThreshold(0.0);
537+
538+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
539+ QCOMPARE(edgeDragArea->dragging(), false);
540+
541+ fakeTimeSource->m_msecsSinceReference = 0;
542+ QTest::touchEvent(view, device).press(0, touchPos.toPoint());
543+
544+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
545+ QCOMPARE(draggingSpy.count(), 1);
546+ QCOMPARE(edgeDragArea->dragging(), true);
547+}
548+
461QTEST_MAIN(tst_DirectionalDragArea)
549QTEST_MAIN(tst_DirectionalDragArea)
462
550
463#include "tst_DirectionalDragArea.moc"
551#include "tst_DirectionalDragArea.moc"
tests/qmltests/CMakeLists.txt+2−1
@@ -2,6 +2,7 @@
2include(QmlTest)
2include(QmlTest)
3
3
4add_subdirectory(plugins)
4add_subdirectory(plugins)
5+add_subdirectory(Components)
5
6
6set(qmltest_DEFAULT_IMPORT_PATHS
7set(qmltest_DEFAULT_IMPORT_PATHS
7 ${CMAKE_CURRENT_BINARY_DIR}/plugins
8 ${CMAKE_CURRENT_BINARY_DIR}/plugins
@@ -25,9 +26,9 @@ add_qml_test(utils/Unity/Test UnityTest)
25set(qmltest_DEFAULT_TARGETS qmluitests)
26set(qmltest_DEFAULT_TARGETS qmluitests)
26set(qmltest_DEFAULT_NO_ADD_TEST TRUE)
27set(qmltest_DEFAULT_NO_ADD_TEST TRUE)
27set(qmltest_DEFAULT_PROPERTIES "")
28set(qmltest_DEFAULT_PROPERTIES "")
29+add_manual_qml_test(Components DragHandle IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
28add_qml_test(Components DraggingArea)
30add_qml_test(Components DraggingArea)
29add_qml_test(Components FilterGrid IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins)
31add_qml_test(Components FilterGrid IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins)
30−add_qml_test(Components ListViewWithPageHeader)
31add_qml_test(Components ResponsiveFlowView)
32add_qml_test(Components ResponsiveFlowView)
32add_qml_test(Components ResponsiveGridView)
33add_qml_test(Components ResponsiveGridView)
33add_qml_test(Components Revealer)
34add_qml_test(Components Revealer)
tests/qmltests/Components/CMakeLists.txtnew file+23
@@ -0,0 +1,23 @@
1+########## tst_DragHandle
2+
3+include_directories(
4+ ${CMAKE_SOURCE_DIR}/plugins/Ubuntu/Gestures
5+ ${CMAKE_CURRENT_BINARY_DIR}
6+ )
7+
8+set(testCommand
9+ LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/plugins/Ubuntu/Gestures
10+ ${CMAKE_CURRENT_BINARY_DIR}/DragHandleTestExec
11+ -o ${CMAKE_BINARY_DIR}/DragHandleTest.xml,xunitxml
12+ -o -,txt)
13+
14+add_custom_target(testDragHandle ${testCommand})
15+add_dependencies(qmluitests testDragHandle)
16+add_dependencies(testDragHandle DragHandleTestExec)
17+
18+add_executable(DragHandleTestExec tst_DragHandle.cpp)
19+qt5_use_modules(DragHandleTestExec Test Core Qml Gui Quick)
20+target_link_libraries(DragHandleTestExec UbuntuGestureQml)
21+
22+add_definitions(-DUBUNTU_GESTURES_PLUGIN_DIR="${CMAKE_BINARY_DIR}/plugins")
23+add_definitions(-DTEST_DIR="${CMAKE_CURRENT_LIST_DIR}")
tests/qmltests/Components/tst_DragHandle.cppnew file+395
@@ -0,0 +1,395 @@
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 <functional>
18+#include <QtTest/QtTest>
19+#include <QtCore/QObject>
20+#include <qpa/qwindowsysteminterface.h>
21+#include <QtQuick/QQuickView>
22+#include <QtQml/QQmlEngine>
23+
24+#include <DirectionalDragArea.h>
25+
26+class FakeTimer : public UbuntuGestures::AbstractTimer
27+{
28+ Q_OBJECT
29+public:
30+ FakeTimer(QObject *parent = 0)
31+ : UbuntuGestures::AbstractTimer(parent)
32+ {}
33+
34+ virtual int interval() const { return m_duration; }
35+ virtual void setInterval(int msecs) { m_duration = msecs; }
36+private:
37+ int m_duration;
38+};
39+
40+class FakeTimeSource : public UbuntuGestures::TimeSource
41+{
42+public:
43+ FakeTimeSource() { m_msecsSinceReference = 0; }
44+ virtual qint64 msecsSinceReference() {return m_msecsSinceReference;}
45+ qint64 m_msecsSinceReference;
46+};
47+
48+class tst_DragHandle: public QObject
49+{
50+ Q_OBJECT
51+public:
52+ tst_DragHandle() : m_device(0) { }
53+private Q_SLOTS:
54+ void initTestCase(); // will be called before the first test function is executed
55+ void cleanupTestCase(); // will be called after the last test function was executed.
56+
57+ void init(); // called right before each and every test function is executed
58+ void cleanup(); // called right after each and every test function is executed
59+
60+ void dragThreshold_horizontal();
61+ void dragThreshold_vertical();
62+ void stretch_horizontal();
63+ void stretch_vertical();
64+ void hintingAnimation();
65+
66+private:
67+ void flickAndHold(DirectionalDragArea *dragHandle, qreal distance);
68+ DirectionalDragArea *fetchAndSetupDragHandle(const char *objectName);
69+ qreal fetchDragThreshold(DirectionalDragArea *dragHandle);
70+ void tryCompare(std::function<qreal ()> actualFunc, qreal expectedValue);
71+
72+ QQuickView *createView();
73+ QQuickView *m_view;
74+ QTouchDevice *m_device;
75+ FakeTimer *m_fakeTimer;
76+ FakeTimeSource *m_fakeTimeSource;
77+};
78+
79+
80+void tst_DragHandle::initTestCase()
81+{
82+ if (!m_device) {
83+ m_device = new QTouchDevice;
84+ m_device->setType(QTouchDevice::TouchScreen);
85+ QWindowSystemInterface::registerTouchDevice(m_device);
86+ }
87+
88+ m_view = 0;
89+}
90+
91+void tst_DragHandle::cleanupTestCase()
92+{
93+}
94+
95+void tst_DragHandle::init()
96+{
97+ m_view = createView();
98+ m_view->setSource(QUrl::fromLocalFile(TEST_DIR"/tst_DragHandle.qml"));
99+ m_view->show();
100+ QVERIFY(QTest::qWaitForWindowExposed(m_view));
101+ QVERIFY(m_view->rootObject() != 0);
102+ qApp->processEvents();
103+
104+ m_fakeTimer = new FakeTimer;
105+ m_fakeTimeSource = new FakeTimeSource;
106+}
107+
108+void tst_DragHandle::cleanup()
109+{
110+ delete m_view;
111+ m_view = 0;
112+
113+ delete m_fakeTimer;
114+ m_fakeTimer = 0;
115+
116+ delete m_fakeTimeSource;
117+ m_fakeTimeSource = 0;
118+}
119+
120+QQuickView *tst_DragHandle::createView()
121+{
122+ QQuickView *window = new QQuickView(0);
123+ window->setResizeMode(QQuickView::SizeRootObjectToView);
124+ window->resize(600, 600);
125+ window->engine()->addImportPath(QLatin1String(UBUNTU_GESTURES_PLUGIN_DIR));
126+ window->engine()->addImportPath(QLatin1String(TEST_DIR));
127+
128+ return window;
129+}
130+
131+void tst_DragHandle::tryCompare(std::function<qreal ()> actualFunc,
132+ qreal expectedValue)
133+{
134+ int waitCount = 0;
135+ while (actualFunc() != expectedValue && waitCount < 100) {
136+ QTest::qWait(50);
137+ ++waitCount;
138+ }
139+ QCOMPARE(actualFunc(), expectedValue);
140+}
141+
142+namespace {
143+QPointF calculateDirectionVector(DirectionalDragArea *edgeDragArea)
144+{
145+
146+ switch (edgeDragArea->direction()) {
147+ case Direction::Upwards:
148+ return QPointF(0, -1);
149+ case Direction::Downwards:
150+ return QPointF(0, 1);
151+ case Direction::Leftwards:
152+ return QPointF(-1, 0);
153+ default: // Direction::Rightwards:
154+ return QPointF(1, 0);
155+ }
156+}
157+}
158+
159+void tst_DragHandle::flickAndHold(DirectionalDragArea *dragHandle,
160+ qreal distance)
161+{
162+ QPointF initialTouchPos = dragHandle->mapToScene(
163+ QPointF(dragHandle->width() / 2.0, dragHandle->height() / 2.0));
164+ QPointF touchPoint = initialTouchPos;
165+ int numSteps = 10;
166+ qint64 flickTimeMs = 500;
167+ qint64 timeStep = flickTimeMs / numSteps;
168+
169+ QPointF dragDirectionVector = calculateDirectionVector(dragHandle);
170+ QPointF touchMovement = dragDirectionVector * (distance / (qreal)numSteps);
171+
172+ QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
173+
174+ for (int i = 0; i < numSteps; ++i) {
175+ touchPoint += touchMovement;
176+ m_fakeTimeSource->m_msecsSinceReference += timeStep;
177+ QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
178+ }
179+
180+ // Wait for quite a bit before finally releasing to make a very low flick/release
181+ // speed.
182+ m_fakeTimeSource->m_msecsSinceReference += 5000;
183+ QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
184+}
185+
186+DirectionalDragArea *tst_DragHandle::fetchAndSetupDragHandle(const char *objectName)
187+{
188+ DirectionalDragArea *dragHandle =
189+ m_view->rootObject()->findChild<DirectionalDragArea*>(objectName);
190+ Q_ASSERT(dragHandle != 0);
191+ dragHandle->setRecognitionTimer(m_fakeTimer);
192+ dragHandle->setTimeSource(m_fakeTimeSource);
193+
194+ AxisVelocityCalculator *edgeDragEvaluator =
195+ dragHandle->findChild<AxisVelocityCalculator*>("edgeDragEvaluator");
196+ Q_ASSERT(edgeDragEvaluator != 0);
197+ edgeDragEvaluator->setTimeSource(m_fakeTimeSource);
198+
199+ return dragHandle;
200+}
201+
202+qreal tst_DragHandle::fetchDragThreshold(DirectionalDragArea *dragHandle)
203+{
204+ AxisVelocityCalculator *edgeDragEvaluator =
205+ dragHandle->findChild<AxisVelocityCalculator*>("edgeDragEvaluator");
206+ Q_ASSERT(edgeDragEvaluator != 0);
207+
208+ return edgeDragEvaluator->property("dragThreshold").toReal();
209+}
210+
211+/*
212+ Checks that ending a low-speed drag before dragThreshold results in the
213+ Showable getting back to its original position, whereas ending after dragThreshold
214+ results in Showable continuing until reaching its new states (shown or hidden)
215+ */
216+void tst_DragHandle::dragThreshold_horizontal()
217+{
218+ DirectionalDragArea *dragHandle = fetchAndSetupDragHandle("rightwardsDragHandle");
219+
220+ qreal dragThreshold = fetchDragThreshold(dragHandle);
221+
222+ // end before the threshold
223+ flickAndHold(dragHandle, dragThreshold * 0.7);
224+
225+ // should rollback
226+ QQuickItem *parentItem = dragHandle->parentItem();
227+ tryCompare([&](){ return parentItem->x(); }, -parentItem->width());
228+ QCOMPARE(parentItem->property("shown").toBool(), false);
229+
230+ // end after the threshold
231+ flickAndHold(dragHandle, dragThreshold * 1.2);
232+
233+ // should keep going until completion
234+ tryCompare([&](){ return parentItem->x(); }, 0);
235+ QCOMPARE(parentItem->property("shown").toBool(), true);
236+
237+ dragHandle = fetchAndSetupDragHandle("leftwardsDragHandle");
238+
239+ dragThreshold = fetchDragThreshold(dragHandle);
240+
241+ // end before the threshold
242+ flickAndHold(dragHandle, dragThreshold * 0.7);
243+
244+ // should rollback
245+ tryCompare([&](){ return parentItem->x(); }, 0);
246+ QCOMPARE(parentItem->property("shown").toBool(), true);
247+
248+ // end after the threshold
249+ flickAndHold(dragHandle, dragThreshold * 1.2);
250+
251+ // should keep going until completion
252+ tryCompare([&](){ return parentItem->x(); }, -parentItem->width());
253+ QCOMPARE(parentItem->property("shown").toBool(), false);
254+}
255+
256+void tst_DragHandle::dragThreshold_vertical()
257+{
258+ DirectionalDragArea *dragHandle = fetchAndSetupDragHandle("downwardsDragHandle");
259+
260+ qreal dragThreshold = fetchDragThreshold(dragHandle);
261+
262+ // end before the threshold
263+ flickAndHold(dragHandle, dragThreshold * 0.7);
264+
265+ // should rollback
266+ QQuickItem *parentItem = dragHandle->parentItem();
267+ tryCompare([&](){ return parentItem->y(); }, -parentItem->height());
268+ QCOMPARE(parentItem->property("shown").toBool(), false);
269+
270+ // end after the threshold
271+ flickAndHold(dragHandle, dragThreshold * 1.2);
272+
273+ // should keep going until completion
274+ tryCompare([&](){ return parentItem->y(); }, 0);
275+ QCOMPARE(parentItem->property("shown").toBool(), true);
276+
277+ dragHandle = fetchAndSetupDragHandle("upwardsDragHandle");
278+
279+ dragThreshold = fetchDragThreshold(dragHandle);
280+
281+ // end before the threshold
282+ flickAndHold(dragHandle, dragThreshold * 0.7);
283+
284+ // should rollback
285+ tryCompare([&](){ return parentItem->y(); }, 0);
286+ QCOMPARE(parentItem->property("shown").toBool(), true);
287+
288+ // end after the threshold
289+ flickAndHold(dragHandle, dragThreshold * 1.2);
290+
291+ // should keep going until completion
292+ tryCompare([&](){ return parentItem->y(); }, -parentItem->height());
293+ QCOMPARE(parentItem->property("shown").toBool(), false);
294+}
295+
296+/*
297+ Checks that when the stretch property is true, dragging the DragHandle increases
298+ the width or height (depending on its direction) of its parent Showable
299+ */
300+void tst_DragHandle::stretch_horizontal()
301+{
302+ DirectionalDragArea *dragHandle = fetchAndSetupDragHandle("rightwardsDragHandle");
303+ qreal totalDragDistance = dragHandle->property("maxTotalDragDistance").toReal();
304+ QQuickItem *parentItem = dragHandle->parentItem();
305+
306+ // enable strech mode
307+ m_view->rootObject()->setProperty("stretch", QVariant(true));
308+
309+ QCOMPARE(parentItem->width(), 0.0);
310+
311+ // flick all the way
312+ flickAndHold(dragHandle, totalDragDistance);
313+
314+ // should keep going until completion
315+ // Parent item should now have its full height
316+ tryCompare([&](){ return parentItem->width(); }, totalDragDistance);
317+ QCOMPARE(parentItem->property("shown").toBool(), true);
318+
319+ dragHandle = fetchAndSetupDragHandle("leftwardsDragHandle");
320+
321+ // flick all the way
322+ flickAndHold(dragHandle, totalDragDistance);
323+
324+ // should keep going until completion
325+ // Parent item should now have its full height
326+ tryCompare([&](){ return parentItem->width(); }, 0.0);
327+ QCOMPARE(parentItem->property("shown").toBool(), false);
328+}
329+
330+void tst_DragHandle::stretch_vertical()
331+{
332+ DirectionalDragArea *dragHandle = fetchAndSetupDragHandle("downwardsDragHandle");
333+ qreal totalDragDistance = dragHandle->property("maxTotalDragDistance").toReal();
334+ QQuickItem *parentItem = dragHandle->parentItem();
335+
336+ // enable strech mode
337+ m_view->rootObject()->setProperty("stretch", QVariant(true));
338+
339+ QCOMPARE(parentItem->height(), 0.0);
340+
341+ // flick all the way
342+ flickAndHold(dragHandle, totalDragDistance);
343+
344+ // should keep going until completion
345+ // Parent item should now have its full height
346+ tryCompare([&](){ return parentItem->height(); }, totalDragDistance);
347+ QCOMPARE(parentItem->property("shown").toBool(), true);
348+
349+ dragHandle = fetchAndSetupDragHandle("upwardsDragHandle");
350+
351+ // flick all the way
352+ flickAndHold(dragHandle, totalDragDistance);
353+
354+ // should keep going until completion
355+ // Parent item should now have its full height
356+ tryCompare([&](){ return parentItem->height(); }, 0.0);
357+ QCOMPARE(parentItem->property("shown").toBool(), false);
358+}
359+
360+/*
361+ Set DragHandle.hintDisplacement to a value bigger than zero.
362+ Then lay a finger on the DragHandle.
363+ The expected behavior is that it will move or strech its parent Showable
364+ by hintDisplacement pixels.
365+ */
366+void tst_DragHandle::hintingAnimation()
367+{
368+ DirectionalDragArea *dragHandle = fetchAndSetupDragHandle("downwardsDragHandle");
369+ QQuickItem *parentItem = dragHandle->parentItem();
370+ qreal hintDisplacement = 100.0;
371+
372+ // enable hinting animations and stretch mode
373+ m_view->rootObject()->setProperty("hintDisplacement", QVariant(hintDisplacement));
374+ m_view->rootObject()->setProperty("stretch", QVariant(true));
375+
376+ QCOMPARE(parentItem->height(), 0.0);
377+
378+ QPointF initialTouchPos = dragHandle->mapToScene(
379+ QPointF(dragHandle->width() / 2.0, dragHandle->height() / 2.0));
380+ QPointF touchPoint = initialTouchPos;
381+
382+ // Pressing causes the Showable to be stretched by hintDisplacement pixels
383+ QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
384+ tryCompare([&](){ return parentItem->height(); }, hintDisplacement);
385+
386+ // Releasing causes the Showable to shrink back to 0 pixels.
387+ QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
388+ tryCompare([&](){ return parentItem->height(); }, 0.0);
389+
390+ QCOMPARE(parentItem->property("shown").toBool(), false);
391+}
392+
393+QTEST_MAIN(tst_DragHandle)
394+
395+#include "tst_DragHandle.moc"
tests/qmltests/Components/tst_DragHandle.qmlnew file+146
@@ -0,0 +1,146 @@
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 "../../../Components"
19+import "tst_DragHandle"
20+import Ubuntu.Components 0.1
21+import Ubuntu.Gestures 0.1
22+
23+/*
24+ Two blue fullscreen Showables (a vertical and a horizontal one) with red handles you
25+ can use to drag them away and green handles to drag them in.
26+
27+ A black vertical line marks the point where a drag needs no forward velocity to
28+ achieve auto-completion (i.e., get Showable.show() called after touch release).
29+ */
30+Item {
31+ id: root
32+ width: 700
33+ height: 500
34+
35+ property var dragHandle
36+
37+ property bool stretch: false
38+ property real hintDisplacement: 0
39+
40+ VerticalShowable {
41+ onDragHandleRecognizedGesture: { root.dragHandle = dragHandle }
42+ stretch: root.stretch
43+ hintDisplacement: root.hintDisplacement
44+ }
45+
46+ HorizontalShowable {
47+ onDragHandleRecognizedGesture: { root.dragHandle = dragHandle }
48+ stretch: root.stretch
49+ hintDisplacement: root.hintDisplacement
50+ }
51+
52+ // Visually mark drag threshold
53+ Rectangle {
54+ color: "black"
55+ width: 2
56+ height: parent.height
57+
58+ visible: dragHandle !== undefined && Direction.isHorizontal(dragHandle.direction)
59+
60+ x: {
61+ if (dragHandle) {
62+ if (dragHandle.direction === Direction.Rightwards) {
63+ dragHandle.edgeDragEvaluator.dragThreshold;
64+ } else {
65+ parent.width - dragHandle.edgeDragEvaluator.dragThreshold;
66+ }
67+ } else {
68+ 0
69+ }
70+ }
71+ }
72+ Rectangle {
73+ color: "black";
74+ height: 2
75+ width: parent.width
76+
77+ visible: dragHandle !== undefined && Direction.isVertical(dragHandle.direction)
78+
79+ y: {
80+ if (dragHandle) {
81+ if (dragHandle.direction === Direction.Downwards) {
82+ dragHandle.edgeDragEvaluator.dragThreshold;
83+ } else {
84+ parent.height - dragHandle.edgeDragEvaluator.dragThreshold;
85+ }
86+ } else {
87+ 0
88+ }
89+ }
90+ }
91+
92+ // Display velocities
93+ Rectangle {
94+ width: childrenRect.width
95+ height: childrenRect.height
96+ color: "white"
97+ opacity: 0.4
98+ Text {
99+ id: velocityText
100+ font.pixelSize: units.gu(2)
101+ text: {
102+ if (dragHandle !== undefined) {
103+ "Velocity: " + (dragHandle.edgeDragEvaluator.velocity * 1000);
104+ } else {
105+ "Velocity: -";
106+ }
107+ }
108+ }
109+ Text {
110+ anchors.top: velocityText.bottom
111+ font.pixelSize: units.gu(2)
112+ text: {
113+ if (dragHandle !== undefined) {
114+ "Minimum velocity: " + (dragHandle.edgeDragEvaluator.minVelocity * 1000);
115+ } else {
116+ "Minimum velocity: -";
117+ }
118+ }
119+ }
120+ }
121+
122+ TestButton {
123+ id: stretchButton
124+ anchors.bottom: parent.bottom
125+ anchors.left: parent.left
126+ anchors.margins: units.gu(1)
127+
128+ text: root.stretch ? "stretch" : "move"
129+ onClicked: { root.stretch = !root.stretch; }
130+ }
131+
132+ TestButton {
133+ anchors.bottom: parent.bottom
134+ anchors.left: stretchButton.right
135+ anchors.margins: units.gu(1)
136+
137+ text: root.hintDisplacement > 0 ? "hint" : "no hint"
138+ onClicked: {
139+ if (root.hintDisplacement > 0) {
140+ root.hintDisplacement = 0;
141+ } else {
142+ root.hintDisplacement = units.gu(6);
143+ }
144+ }
145+ }
146+}
tests/qmltests/Components/tst_DragHandle/HorizontalShowable.qmlnew file+100
@@ -0,0 +1,100 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import "../../../../Components"
19+import Ubuntu.Components 0.1
20+import Ubuntu.Gestures 0.1
21+
22+Showable {
23+ id: showable
24+ x: stretch ? 0 : -width
25+ width: stretch ? 0 : parent.width
26+ height: parent.height
27+
28+ property bool stretch
29+ property real hintDisplacement
30+
31+ onStretchChanged: {
32+ if (stretch) {
33+ x = 0;
34+ width = 0;
35+ } else {
36+ x = -parent.width;
37+ width = parent.width;
38+ }
39+ }
40+
41+ shown: false
42+
43+ signal dragHandleRecognizedGesture(var dragHandle)
44+
45+ property string animatedProp: stretch ? "width" : "x"
46+ property real propValueWhenShown: stretch ? parent.width : 0
47+ property real propValueWhenHidden: stretch ? 0 : -width
48+
49+ showAnimation: StandardAnimation { property: animatedProp; to: propValueWhenShown }
50+ hideAnimation: StandardAnimation { property: animatedProp; to: propValueWhenHidden }
51+
52+ Image { source: "UnityLogo.png"; anchors.fill: parent }
53+
54+ DragHandle {
55+ objectName: "leftwardsDragHandle"
56+ id: leftwardsDragHandle
57+ anchors.top: parent.top
58+ anchors.bottom: parent.bottom
59+ anchors.right: parent.right
60+
61+ width: units.gu(2)
62+
63+ direction: Direction.Leftwards
64+ stretch: showable.stretch
65+ maxTotalDragDistance: showable.parent.width
66+ hintDisplacement: showable.hintDisplacement
67+
68+ onStatusChanged: {
69+ if (status === DirectionalDragArea.Recognized) {
70+ dragHandleRecognizedGesture(leftwardsDragHandle);
71+ }
72+ }
73+
74+ Rectangle { color: "red"; anchors.fill: parent }
75+ }
76+
77+ DragHandle {
78+ objectName: "rightwardsDragHandle"
79+ id: rightwardsDragHandle
80+ anchors.top: parent.top
81+ anchors.bottom: parent.bottom
82+ anchors.left: parent.right
83+
84+ width: units.gu(2)
85+
86+ direction: Direction.Rightwards
87+ stretch: showable.stretch
88+ maxTotalDragDistance: showable.parent.width
89+ hintDisplacement: showable.hintDisplacement
90+
91+ onStatusChanged: {
92+ if (status === DirectionalDragArea.Recognized) {
93+ dragHandleRecognizedGesture(rightwardsDragHandle);
94+ }
95+ }
96+
97+ Rectangle { color: "green"; anchors.fill: parent }
98+ }
99+
100+}
tests/qmltests/Components/tst_DragHandle/TestButton.qmlnew file+41
@@ -0,0 +1,41 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+
20+Rectangle {
21+ id: rect
22+ width: childrenRect.width
23+ height: childrenRect.height
24+
25+ property alias text: textComponent.text
26+
27+ signal clicked
28+
29+ color: "yellow"
30+ Text {
31+ id: textComponent
32+ font.pixelSize: units.gu(2)
33+ text: root.stretch ? "stretch" : "move"
34+ MouseArea {
35+ anchors.fill: parent
36+ onClicked: {
37+ rect.clicked()
38+ }
39+ }
40+ }
41+}
tests/qmltests/Components/tst_DragHandle/UnityLogo.pngnew file

Binary file not shown.

tests/qmltests/Components/tst_DragHandle/VerticalShowable.qmlnew file+100
@@ -0,0 +1,100 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import "../../../../Components"
19+import Ubuntu.Components 0.1
20+import Ubuntu.Gestures 0.1
21+
22+Showable {
23+ id: showable
24+ y: stretch ? 0 : -height
25+ width: parent.width
26+ height: stretch ? 0 : parent.height
27+
28+ property bool stretch
29+ property real hintDisplacement
30+
31+ onStretchChanged: {
32+ if (stretch) {
33+ y = 0;
34+ height = 0;
35+ } else {
36+ y = -parent.height;
37+ height = parent.height;
38+ }
39+ }
40+
41+ shown: false
42+
43+ signal dragHandleRecognizedGesture(var dragHandle)
44+
45+ property string animatedProp: stretch ? "height" : "y"
46+ property real propValueWhenShown: stretch ? parent.height : 0
47+ property real propValueWhenHidden: stretch ? 0 : -height
48+
49+ showAnimation: StandardAnimation { property: animatedProp; to: propValueWhenShown }
50+ hideAnimation: StandardAnimation { property: animatedProp; to: propValueWhenHidden }
51+
52+ Image { source: "UnityLogo.png"; anchors.fill: parent }
53+
54+ DragHandle {
55+ objectName: "upwardsDragHandle"
56+ id: upwardsDragHandle
57+ anchors.left: parent.left
58+ anchors.right: parent.right
59+ anchors.bottom: parent.bottom
60+
61+ height: units.gu(2)
62+
63+ direction: Direction.Upwards
64+ stretch: showable.stretch
65+ maxTotalDragDistance: showable.parent.height
66+ hintDisplacement: showable.hintDisplacement
67+
68+ onStatusChanged: {
69+ if (status === DirectionalDragArea.Recognized) {
70+ dragHandleRecognizedGesture(upwardsDragHandle);
71+ }
72+ }
73+
74+ Rectangle { color: "red"; anchors.fill: parent }
75+ }
76+
77+ DragHandle {
78+ objectName: "downwardsDragHandle"
79+ id: downwardsDragHandle
80+ anchors.left: parent.left
81+ anchors.right: parent.right
82+ anchors.top: parent.bottom
83+
84+ height: units.gu(2)
85+
86+ direction: Direction.Downwards
87+ stretch: showable.stretch
88+ maxTotalDragDistance: showable.parent.height
89+ hintDisplacement: showable.hintDisplacement
90+
91+ onStatusChanged: {
92+ if (status === DirectionalDragArea.Recognized) {
93+ dragHandleRecognizedGesture(downwardsDragHandle);
94+ }
95+ }
96+
97+ Rectangle { color: "green"; anchors.fill: parent }
98+ }
99+
100+}
tests/qmltests/Components/tst_ListViewWithPageHeader.qmldeleted−351
@@ -1,351 +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 ".."
20−import "../../../Components"
21−import Ubuntu.Components.ListItems 0.1 as ListItem
22−import Ubuntu.Components 0.1
23−import Unity.Test 0.1 as UT
24−
25−Item {
26− id: root
27− width: units.gu(40)
28− height: units.gu(80)
29−
30− ListModel {
31− id: animalsModel
32− ListElement { name: "Parrot"; size: "Small" }
33− ListElement { name: "Guinea pig"; size: "Small" }
34− ListElement { name: "Mouse"; size: "Small" }
35− ListElement { name: "Sparrow"; size: "Small" }
36− ListElement { name: "Dog"; size: "Medium" }
37− ListElement { name: "Cat"; size: "Medium" }
38− ListElement { name: "Dolphin"; size: "Medium" }
39− ListElement { name: "Seal"; size: "Medium" }
40− ListElement { name: "Elephant"; size: "Large" }
41− ListElement { name: "Blue whale"; size: "Large" }
42− ListElement { name: "Rhino"; size: "Large" }
43− ListElement { name: "Ostrich"; size: "Large" }
44− ListElement { name: "Sperm whale"; size: "Large" }
45− ListElement { name: "Giraffe"; size: "Large" }
46− ListElement { name: "Parrot"; size: "Small" }
47− ListElement { name: "Guinea pig"; size: "Small" }
48− ListElement { name: "Mouse"; size: "Small" }
49− ListElement { name: "Sparrow"; size: "Small" }
50− ListElement { name: "Dog"; size: "Medium" }
51− ListElement { name: "Cat"; size: "Medium" }
52− ListElement { name: "Dolphin"; size: "Medium" }
53− ListElement { name: "Seal"; size: "Medium" }
54− ListElement { name: "Elephant"; size: "Large" }
55− ListElement { name: "Blue whale"; size: "Large" }
56− ListElement { name: "Rhino"; size: "Large" }
57− ListElement { name: "Ostrich"; size: "Large" }
58− ListElement { name: "Sperm whale"; size: "Large" }
59− ListElement { name: "Giraffe"; size: "Large" }
60− ListElement { name: "Parrot"; size: "Small" }
61− ListElement { name: "Guinea pig"; size: "Small" }
62− ListElement { name: "Mouse"; size: "Small" }
63− ListElement { name: "Sparrow"; size: "Small" }
64− ListElement { name: "Dog"; size: "Medium" }
65− ListElement { name: "Cat"; size: "Medium" }
66− ListElement { name: "Dolphin"; size: "Medium" }
67− ListElement { name: "Seal"; size: "Medium" }
68− ListElement { name: "Elephant"; size: "Large" }
69− ListElement { name: "Blue whale"; size: "Large" }
70− ListElement { name: "Rhino"; size: "Large" }
71− ListElement { name: "Ostrich"; size: "Large" }
72− ListElement { name: "Sperm whale"; size: "Large" }
73− ListElement { name: "Giraffe"; size: "Large" }
74− ListElement { name: "Parrot"; size: "Small" }
75− ListElement { name: "Guinea pig"; size: "Small" }
76− ListElement { name: "Mouse"; size: "Small" }
77− ListElement { name: "Sparrow"; size: "Small" }
78− ListElement { name: "Dog"; size: "Medium" }
79− ListElement { name: "Cat"; size: "Medium" }
80− ListElement { name: "Dolphin"; size: "Medium" }
81− ListElement { name: "Seal"; size: "Medium" }
82− ListElement { name: "Elephant"; size: "Large" }
83− ListElement { name: "Blue whale"; size: "Large" }
84− ListElement { name: "Rhino"; size: "Large" }
85− ListElement { name: "Ostrich"; size: "Large" }
86− ListElement { name: "Sperm whale"; size: "Large" }
87− ListElement { name: "Giraffe"; size: "Large" }
88− }
89−
90− ListViewWithPageHeader {
91− id: listView
92− anchors.fill: parent
93− model: animalsModel
94−
95− delegate: Item {
96− height: units.gu(6)
97− anchors {
98− left: parent.left
99− right: parent.right
100− }
101−
102− Label {
103− id: label
104− anchors.fill: parent
105− text: name
106− verticalAlignment: Text.AlignVCenter
107− }
108− }
109−
110− sectionProperty: "size"
111− sectionDelegate: Rectangle {
112− anchors {
113− left: (parent) ? parent.left : undefined
114− right: (parent) ? parent.right : undefined
115− }
116− height: units.gu(5)
117− color: "lightsteelblue"
118−
119− Label {
120− id: label
121− anchors.fill: parent
122− text: section
123− verticalAlignment: Text.AlignVCenter
124− }
125− }
126−
127− pageHeader: PageHeader {
128− id: pageHeader
129− anchors {
130− left: parent.left
131− right: parent.right
132− }
133− text: "Animals"
134− }
135− }
136−
137−
138−
139−
140− UT.UnityTestCase {
141− name: "ListViewWithPageHeader"
142− when: windowShown
143−
144− readonly property real xPos: listView.width / 2
145− readonly property real headerHeight: pageHeader.height
146−
147− /**************************** Helper functions ****************************/
148− function listViewFirstSectionHeaderYPosition() {
149− return Math.round(listView.pageHeader.mapToItem(listView).y); //round as using floats
150− }
151−
152− function firstSectionHeaderYPosition() {
153− return Math.round(listView.view.children[0].mapToItem(listView).y);
154− }
155−
156− function cleanup() {
157− listView.positionAtBeginning();
158− // wait for list position to reset
159− tryCompareFunction(listViewFirstSectionHeaderYPosition, 0);
160− tryCompare(listView.view.contentY, 0);
161− }
162−
163− // these functions are hand-crafted to move the Flickable down/up one pixel
164− function swipeDown1Pixel(item) {
165− mousePress(item, xPos, 15);
166− mouseMove(item, xPos, 14, 100);
167− mouseMove(item, xPos, 10, 100);
168− mouseMove(item, xPos, 6, 100);
169− mouseMove(item, xPos, 3, 100);
170− mouseMove(item, xPos, 1, 100);
171− mouseMove(item, xPos, 0, 100);
172− mouseRelease(item, xPos, 0);
173− }
174−
175− function swipeUp1Pixel(item) {
176− mousePress(item, xPos, 0);
177− mouseMove(item, xPos, 1, 100);
178− mouseMove(item, xPos, 5, 100);
179− mouseMove(item, xPos, 9, 100);
180− mouseMove(item, xPos, 12, 100);
181− mouseMove(item, xPos, 14, 100);
182− mouseMove(item, xPos, 15, 100);
183− mouseRelease(item, xPos, 15);
184− }
185−
186− /******************************* Test cases *******************************/
187−
188− /* Check the initial positions of components are correct */
189− function test_initialState() {
190− compare(listViewFirstSectionHeaderYPosition(), 0);
191− compare(listView.view.contentY, 0);
192−
193− // Check that the section delegate is positioned underneath the header
194− // First section delegate is the first child of the view
195− tryCompareFunction(firstSectionHeaderYPosition, headerHeight);
196− }
197−
198− /* Check the header moves up one pixel when the view is moved up by one pixel */
199− function test_headerPositionAfterDownMoveByOnePixel() {
200− swipeDown1Pixel(listView)
201−
202− tryCompareFunction(listViewFirstSectionHeaderYPosition, -1);
203− tryCompareFunction(firstSectionHeaderYPosition, headerHeight - 1);
204− tryCompare(listView.view.contentY, -1);
205− }
206−
207− /* Check the header position is y=0 when view moved up and then down by one pixel */
208− function test_headerPositionAfterDownAndThenUpMoveByOne() {
209− swipeDown1Pixel(listView)
210−
211− tryCompareFunction(listViewFirstSectionHeaderYPosition, -1);
212− tryCompare(listView.view.contentY, -1);
213−
214− // these operations move the Flickabe up one pixel
215− swipeUp1Pixel(listView);
216−
217− tryCompare(listView.view.contentY, 0);
218− // tryCompareFunction(listViewFirstSectionHeaderYPosition, 0) //FIXME - this fails due to bug in LVWPH
219− tryCompareFunction(firstSectionHeaderYPosition, headerHeight)
220− }
221−
222− /* Check after a big flick the header is moved off-screen, with the header bottom
223− placed just above the view */
224− function test_headerPositionAfterDownMove() {
225− // move the Flickabe up to hide header
226− listView.flick(0, -10000);
227−
228− // wait for flick to finish
229− tryCompare(listView.moving, false);
230−
231− tryCompareFunction(listViewFirstSectionHeaderYPosition, -headerHeight);
232− }
233−
234− /* Check when header off-screen, moving down the view by one pixel moves the header
235− down by one pixel */
236− function test_hiddenHeaderPositionAfterUpMoveByOnePixel() {
237− // move the Flickabe up to hide header
238− listView.flick(0, -10000);
239−
240− // wait for flick to fully hide header
241− tryCompareFunction(listViewFirstSectionHeaderYPosition, -headerHeight);
242−
243− swipeUp1Pixel(listView);
244−
245− tryCompareFunction( function() {
246− return Math.floor( listViewFirstSectionHeaderYPosition() ); // need to round to make test more robust
247− }, -headerHeight + 1);
248− }
249−
250− /* Check if up swipe causes list to bounces at the bottom, header stays hidden */
251− function test_upSwipeCausingBounceKeepsHeaderHidden() {
252− // move list to the bottom (will bounce)
253− listView.flick(0, -1000000);
254−
255− // wait for bounce to complete
256− tryCompare(listView.moving, false);
257− tryCompare(listView.view.atYEnd, true);
258−
259− tryCompareFunction(listViewFirstSectionHeaderYPosition, -headerHeight);
260− }
261−
262− /* Check if up swipe causes list to bounces at the bottom, header stays hidden */
263− function test_downSwipeCausingBounceKeepsHeaderVisible() {
264− // move list to the bottom (will bounce)
265− listView.flick(0, -1000000);
266−
267− // wait for bounce to complete
268− tryCompare(listView.moving, false);
269− tryCompare(listView.view.atYBeginning, true);
270−
271− tryCompareFunction(listViewFirstSectionHeaderYPosition, 0);
272− }
273−
274− /* Check if list at top is pulled down further, that the list contents move but the
275− header remains at the top of the view */
276− function test_topDragOverBoundsKeepsHeaderVisible() {
277− // drag list up - but don't release yet
278− mouseFlick(listView,
279− xPos, // from_x
280− 0, // from_y
281− xPos, // to_x
282− 100, true, false, 0.2);
283−
284− // wait for gesture to occur
285− tryCompareFunction(function() { return listView.view.contentY < 20; }, true);
286− tryCompareFunction(listViewFirstSectionHeaderYPosition, 0);
287−
288− mouseRelease(listView, xPos, 400);
289−
290− // ensure list moving to recover from over-bound drag keeps header unchanged
291− tryCompare(listView.view.contentY, 0);
292− tryCompareFunction(listViewFirstSectionHeaderYPosition, 0);
293− }
294−
295− /* Check if list at top is pulled down further, that the list contents move but the
296− header remains at the top of the view */
297− function test_bottomDragOverBoundsKeepsHeaderHidden() {
298− // move list to the bottom (will bounce)
299− listView.flick(0, -1000000);
300−
301− // wait for bounce to complete
302− tryCompare(listView.moving, false);
303− tryCompare(listView.view.atYEnd, true);
304−
305− // drag list up but don't release
306− mouseFlick(listView,
307− xPos, // from_x
308− 0, // from_y
309− xPos, // to_x
310− -listView.height, true, false);
311−
312− tryCompareFunction(listViewFirstSectionHeaderYPosition, -headerHeight);
313−
314− mouseRelease(listView, xPos, -listView.height);
315− // wait for list to reset position
316− tryCompare(listView.moving, false);
317− tryCompare(listView.view.atYEnd, true);
318−
319− // ensure list moving to recover from over-bound drag keeps header unchanged
320− tryCompareFunction(listViewFirstSectionHeaderYPosition, -headerHeight);
321− }
322−
323− /* Check positionAtBeginning() works resets list and header position */
324− function test_positionAtBeginning() {
325− // move the Flickabe up to hide header
326− listView.flick(0, -10000);
327−
328− // wait for gesture to complete
329− tryCompare(listView.moving, false);
330−
331− listView.positionAtBeginning();
332− tryCompareFunction(listViewFirstSectionHeaderYPosition, 0);
333− tryCompare(listView.view.contentY, 0);
334− }
335−
336− /* Check showHeader forces header to appear but list position remains unchanged */
337− function test_showHeader() {
338− // move the Flickabe up to hide header
339− listView.flick(0, -10000);
340−
341− // wait for gesture to complete
342− tryCompare(listView.moving, false);
343−
344− var listContentY = listView.view.contentY;
345−
346− listView.showHeader();
347− tryCompareFunction(listViewFirstSectionHeaderYPosition, 0);
348− tryCompare(listView.view.contentY, listContentY);
349− }
350− }
351−}
tests/qmltests/Components/tst_Stage.qml+1−2
@@ -233,8 +233,7 @@ Rectangle {
233
233
234 var touchX = stage.width - (stage.rightEdgeDraggingAreaWidth / 2)
234 var touchX = stage.width - (stage.rightEdgeDraggingAreaWidth / 2)
235 var touchY = stage.height / 2
235 var touchY = stage.height / 2
236− touchFlick(stage, touchX, touchY,
236+ touchFlick(stage, touchX, touchY, stage.width * 0.25, touchY)
237− touchX - units.gu(5), touchY)
238
237
239 // wait until animations end, if any
238 // wait until animations end, if any
240 tryCompare(stage, "usingScreenshots", false)
239 tryCompare(stage, "usingScreenshots", false)
tests/qmltests/Greeter/tst_Phone.qml+40−1
@@ -28,7 +28,17 @@ Item {
28
28
29 Greeter {
29 Greeter {
30 id: greeter
30 id: greeter
31− anchors.fill: parent
31+ width: parent.width
32+ height: parent.height
33+ x: 0; y: 0
34+
35+ property int minX: 0
36+
37+ onXChanged: {
38+ if (x < minX) {
39+ minX = x;
40+ }
41+ }
32 }
42 }
33
43
34 SignalSpy {
44 SignalSpy {
@@ -63,5 +73,34 @@ Item {
63 tryCompare(greeter, "leftTeaserPressed", false)
73 tryCompare(greeter, "leftTeaserPressed", false)
64 tryCompare(greeter, "rightTeaserPressed", false)
74 tryCompare(greeter, "rightTeaserPressed", false)
65 }
75 }
76+
77+ function test_teaseLockedUnlocked_data() {
78+ return [
79+ {tag: "unlocked", locked: false},
80+ {tag: "locked", locked: true}
81+ ];
82+ }
83+
84+ function test_teaseLockedUnlocked(data) {
85+ tryCompare(greeter, "rightTeaserPressed", false);
86+ tryCompare(greeter, "x", 0);
87+ greeter.locked = data.locked;
88+
89+ mouseClick(greeter, greeter.width - units.gu(5), greeter.height - units.gu(1));
90+ greeter.minX = 0; // This is needed because the transition actually makes x jump once before animating
91+
92+ if (!data.locked) {
93+ // Check if it has been moved over by 2 GUs. Give it a 2 pixel grace area
94+ // because animation duration and teaseTimer are the same duration and
95+ // might cause slight offsets
96+ tryCompareFunction(function() { return greeter.minX <= -units.gu(2) + 2}, true);
97+ } else {
98+ // waiting 100ms to make sure nothing moves
99+ wait(100);
100+ compare(greeter.minX, 0, "Greeter moved even tho its locked");
101+ }
102+ // Wait until we're back to 0
103+ tryCompareFunction(function() { return greeter.x;}, 0);
104+ }
66 }
105 }
67}
106}
tests/qmltests/Launcher/tst_Launcher.qml+40
@@ -43,6 +43,18 @@ Item {
43 onDashItemSelected: {
43 onDashItemSelected: {
44 dashItemSelected_count++;
44 dashItemSelected_count++;
45 }
45 }
46+
47+ property int maxPanelX: 0
48+ }
49+
50+ Connections {
51+ target: testCase.findChild(launcher, "launcherPanel")
52+
53+ onXChanged: {
54+ if (target.x > launcher.maxPanelX) {
55+ launcher.maxPanelX = target.x;
56+ }
57+ }
46 }
58 }
47
59
48 UT.UnityTestCase {
60 UT.UnityTestCase {
@@ -126,5 +138,33 @@ Item {
126 var panel = findChild(launcher, "launcherPanel")
138 var panel = findChild(launcher, "launcherPanel")
127 tryCompare(panel, "x", -panel.width, 1000)
139 tryCompare(panel, "x", -panel.width, 1000)
128 }
140 }
141+
142+
143+ function test_teaseLauncher_data() {
144+ return [
145+ {tag: "available", available: true},
146+ {tag: "not available", available: false}
147+ ];
148+ }
149+
150+ function test_teaseLauncher(data) {
151+ launcher.available = data.available;
152+ launcher.maxPanelX = -launcher.panelWidth;
153+ launcher.tease();
154+
155+ if (data.available) {
156+ // Check if the launcher slides in for units.gu(2). However, as the animation is 200ms
157+ // and the teaseTimer's timeout too, give it a 2 pixels grace distance
158+ tryCompareFunction(
159+ function(){
160+ return launcher.maxPanelX >= -launcher.panelWidth + units.gu(2) - 2;
161+ },
162+ true)
163+ } else {
164+ wait(100)
165+ compare(launcher.maxPanelX, -launcher.panelWidth, "Launcher moved even if it shouldn't")
166+ }
167+ waitUntilLauncherDisappears();
168+ }
129 }
169 }
130}
170}