on xenial help sign in
merged with trunk
commit9a785073a97743a6b35015c0a0a4110cb9f3ce77 authorNick Dedekind <nicholas.dedekind@gmail.com> dateMon 30 Sep 2013, 15:50 (13 years ago) parent1632f9fa5a966b
122 files changed+3150−869
Components/CrossFadeImage.qml−151 Components/EdgeDemo.qml+1−1 Components/EdgeDemoOverlay.qml+3 Components/LazyImage.qml+172 Components/ResponsiveGridView.qml+1−1 Components/VolumeControl.qml+5−20 Components/graphics/close@20.png Dash/Apps/AppPreview.qml+11 Dash/Apps/AppReviews.qml+3 Dash/DashPreview.qml+13 Dash/GenericScopeView.qml+24−8 Dash/Music/MusicFilterGrid.qml+12−2 Greeter/GreeterContent.qml+1−1 MouseTouchAdaptor.cpp+29−12 MouseTouchAdaptor.h+2−5 Panel/Indicators.qml+1 Panel/IndicatorsDataModel.qml−4 Panel/MenuContent.qml+12−2 Shell.qml+22−11 debian/changelog+123 debian/control+1−1 debian/unity8-private.install+1 debian/unity8.install−1 main.cpp−1 plugins/AccountsService/AccountsService.cpp+3−3 plugins/AccountsService/AccountsService.h+6−6 plugins/AccountsService/AccountsServiceDBusAdaptor.cpp+15−15 plugins/AccountsService/AccountsServiceDBusAdaptor.h+2−2 plugins/CMakeLists.txt+1 plugins/ListViewWithPageHeader/listviewwithpageheader.cpp+20−1 plugins/ListViewWithPageHeader/listviewwithpageheader.h+1 plugins/SessionBroadcast/CMakeLists.txt+13 plugins/SessionBroadcast/SessionBroadcast.cpp+41 plugins/SessionBroadcast/SessionBroadcast.h+41 plugins/SessionBroadcast/plugin.cpp+35 plugins/SessionBroadcast/plugin.h+33 plugins/SessionBroadcast/qmldir+3 plugins/Unity/CMakeLists.txt+1 plugins/Unity/Indicators/CMakeLists.txt+1 plugins/Unity/IndicatorsLegacy/Messaging/CMakeLists.txt → plugins/Unity/Indicators/Messaging/CMakeLists.txt plugins/Unity/IndicatorsLegacy/Messaging/qml/ActionButton.qml → plugins/Unity/Indicators/Messaging/qml/ActionButton.qml plugins/Unity/IndicatorsLegacy/Messaging/qml/ActionTextField.qml → plugins/Unity/Indicators/Messaging/qml/ActionTextField.qml+10−7 plugins/Unity/Indicators/Messaging/qml/CMakeLists.txt+5 plugins/Unity/IndicatorsLegacy/Messaging/qml/GroupedMessage.qml → plugins/Unity/Indicators/Messaging/qml/GroupedMessage.qml+13−18 plugins/Unity/IndicatorsLegacy/Messaging/qml/HeroMessage.qml → plugins/Unity/Indicators/Messaging/qml/HeroMessage.qml+25−22 plugins/Unity/IndicatorsLegacy/Messaging/qml/HeroMessageHeader.qml → plugins/Unity/Indicators/Messaging/qml/HeroMessageHeader.qml plugins/Unity/Indicators/Messaging/qml/MessageMenuItemFactory.qml+180 plugins/Unity/IndicatorsLegacy/Messaging/qml/QuickReply.qml → plugins/Unity/Indicators/Messaging/qml/QuickReply.qml+10−5 plugins/Unity/IndicatorsLegacy/Messaging/qml/SimpleTextMessage.qml → plugins/Unity/Indicators/Messaging/qml/SimpleTextMessage.qml+7−4 plugins/Unity/IndicatorsLegacy/Messaging/qml/SnapDecision.qml → plugins/Unity/Indicators/Messaging/qml/SnapDecision.qml+33−14 plugins/Unity/IndicatorsLegacy/Messaging/qml/TextMessage.qml → plugins/Unity/Indicators/Messaging/qml/TextMessage.qml+12−4 plugins/Unity/IndicatorsLegacy/Messaging/qml/qmldir → plugins/Unity/Indicators/Messaging/qml/qmldir+2−2 plugins/Unity/IndicatorsLegacy/Messaging/qml/utils.js → plugins/Unity/Indicators/Messaging/qml/utils.js plugins/Unity/Indicators/plugin.cpp+2 plugins/Unity/Indicators/qml/BaseMenuItem.qml+1−1 plugins/Unity/Indicators/qml/IndicatorPage.qml+33−6 plugins/Unity/Indicators/qml/MenuItemFactory.qml+62−12 plugins/Unity/IndicatorsLegacy/resources/artwork/messaging/default_app.svg → plugins/Unity/Indicators/resources/artwork/messaging/default_app.svg plugins/Unity/IndicatorsLegacy/resources/artwork/messaging/default_contact.png → plugins/Unity/Indicators/resources/artwork/messaging/default_contact.png plugins/Unity/IndicatorsLegacy/resources/artwork/messaging/message_sms01_54px.png → plugins/Unity/Indicators/resources/artwork/messaging/message_sms01_54px.png plugins/Unity/Indicators/resources/indicators.qrc+3 plugins/Unity/IndicatorsLegacy/CMakeLists.txt−1 plugins/Unity/IndicatorsLegacy/Messaging/qml/CMakeLists.txt−5 plugins/Unity/IndicatorsLegacy/Messaging/qml/MessageMenuItem.qml−96 plugins/Unity/IndicatorsLegacy/qml/MenuItemFactory.qml−8 plugins/Unity/IndicatorsLegacy/resources/indicators.qrc−3 plugins/Unity/Launcher/launchermodel.cpp+12−3 plugins/Unity/categories.cpp+12−1 plugins/Unity/iconutils.cpp+1−1 plugins/Unity/plugin.cpp+2 plugins/Unity/preview.cpp+17−2 plugins/Unity/preview.h+7 plugins/Unity/result.cpp+82 plugins/Unity/result.h+69 plugins/Unity/scope.cpp+20−1 plugins/Unity/scope.h+3 plugins/Unity/variantutils.cpp+9 plugins/Unity/variantutils.h+1 po/ca.po+23−17 po/en_AU.po+27−26 po/es.po+5−5 po/fi.po+15−15 po/gl.po+29−29 po/is.po+256 po/it.po+55−48 po/lv.po+21−21 po/ru.po+32−26 po/sl.po+32−27 po/uk.po+26−21 po/xh.po+255 src/Panel/Indicators/CMakeLists.txt−1 src/Panel/Indicators/servicefiles/CMakeLists.txt−14 src/Panel/Indicators/servicefiles/com.canonical.indicator.messages−10 tests/autopilot/unity8/application_lifecycle/__init__.py+20 tests/autopilot/unity8/application_lifecycle/tests/__init__.py tests/autopilot/unity8/application_lifecycle/tests/test_application_lifecycle.py+136 tests/autopilot/unity8/shell/__init__.py+10 tests/autopilot/unity8/shell/tests/__init__.py+4−1 tests/mocks/AccountsService/AccountsService.cpp+3−3 tests/mocks/AccountsService/AccountsService.h+6−6 tests/mocks/Ubuntu/DownloadDaemonListener/MockDownloadTracker.cpp+5 tests/mocks/Unity/fake_preview.cpp+2 tests/mocks/Unity/fake_scope.h+2 tests/plugins/AccountsService/client.cpp+2−2 tests/plugins/ListViewWithPageHeader/CMakeLists.txt+6 tests/plugins/ListViewWithPageHeader/listviewwithpageheadertest.cpp+161 tests/plugins/ListViewWithPageHeader/listviewwithpageheadertestsectionexternalmodel.cpp+251 tests/plugins/ListViewWithPageHeader/test_sectionexternalmodel.qml+74 tests/plugins/Unity/Launcher/launchermodeltest.cpp+61−2 tests/plugins/Unity/previewbindingstest.cpp+27 tests/plugins/Unity/resultstest.cpp+1 tests/qmltests/CMakeLists.txt+1−1 tests/qmltests/Components/tst_CrossFadeImage.qml−125 tests/qmltests/Components/tst_LazyImage.qml+156 tests/qmltests/Components/tst_LazyImage/ImageControls.qml+67 tests/qmltests/Components/tst_LazyImage/portrait.png tests/qmltests/Components/tst_LazyImage/square.png tests/qmltests/Components/tst_LazyImage/wide.png tests/qmltests/Dash/Apps/tst_AppPreview.qml+75−2 tests/qmltests/Dash/tst_DashContent.qml+1−1 tests/qmltests/Dash/tst_GenericScopeView.qml+17 tests/uqmlscene/main.cpp−2
Components/CrossFadeImage.qmldeleted−151
@@ -1,151 +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−
19−Item {
20− property url source
21−
22− /*
23− * true: fade out old image in parallel with fading in the new one.
24− * false: fade in new image above old one.
25− *
26− * The reason why this is required is that crossfading has the isse that in
27− * the middle of the animation, both images are only 50% opaque which make
28− * any background shine through. Not wanted for background images etc, but
29− * wanted for overlays.
30− */
31− property bool crossFade: true
32−
33− /*
34− * true: the very first source url should be faded in already.
35− * false: the very first source url should just be shown without animation.
36− */
37− property bool fadeInFirst: true
38−
39− readonly property size sourceSize: __currentImage.sourceSize
40− readonly property var status: __currentImage ? __currentImage.status : Image.Null
41− readonly property bool running: crossFadeImages.running || nextImageFadeIn.running
42−
43− property Image __currentImage: image1
44− property Image __nextImage: image2
45−
46− function swapImages() {
47− __currentImage.z = 0
48− __nextImage.z = 1
49− if (crossFade) {
50− crossFadeImages.start();
51− } else {
52− nextImageFadeIn.start();
53− }
54−
55− var tmpImage = __currentImage
56− __currentImage = __nextImage
57− __nextImage = tmpImage
58− }
59−
60− onSourceChanged: {
61− // On creation, the souce handler is called before image pointers are set.
62− if (__currentImage === null) {
63− __currentImage = image1;
64− __nextImage = image2;
65− }
66−
67− crossFadeImages.stop();
68− nextImageFadeIn.stop();
69−
70− // Don't fade in initial picture, only fade changes
71− if (__currentImage.source == "" && !fadeInFirst) {
72− __currentImage.source = source;
73− } else {
74− nextImageFadeIn.stop();
75− __nextImage.opacity = 0.0;
76− __nextImage.source = source;
77−
78− // If case the image is still in QML's cache, status will be "Ready" immediately
79− if (__nextImage.status == Image.Ready || __nextImage.source == "") {
80− swapImages();
81− }
82− }
83− }
84−
85− Connections {
86− target: __nextImage
87− onStatusChanged: {
88− if (__nextImage.status == Image.Ready || __nextImage.status == Image.Error) {
89− swapImages();
90− }
91− }
92− }
93−
94− Image {
95− id: image1
96− anchors.fill: parent
97− cache: false
98− asynchronous: true
99− fillMode: Image.PreserveAspectCrop
100− z: 1
101− }
102−
103− Image {
104− id: image2
105− anchors.fill: parent
106− cache: false
107− asynchronous: true
108− fillMode: Image.PreserveAspectCrop
109− z: 0
110− }
111−
112− NumberAnimation {
113− id: nextImageFadeIn
114− target: __nextImage
115− property: "opacity"
116− duration: 400
117− to: 1.0
118− easing.type: Easing.InOutQuad
119−
120− onRunningChanged: {
121− if (!running) {
122− __nextImage.source = "";
123− }
124− }
125− }
126−
127− ParallelAnimation {
128− id: crossFadeImages
129− NumberAnimation {
130− target: __nextImage
131− property: "opacity"
132− duration: 400
133− to: 1.0
134− easing.type: Easing.InOutQuad
135− }
136−
137− NumberAnimation {
138− target: __currentImage
139− property: "opacity"
140− duration: 400
141− to: 0
142− easing.type: Easing.InOutQuad
143− }
144−
145− onRunningChanged: {
146− if (!running) {
147− __nextImage.source = "";
148− }
149− }
150− }
151−}
Components/EdgeDemo.qml+1−1
@@ -169,7 +169,7 @@ Item {
169169 "edge": "bottom",
170170 "title": i18n.tr("Close"),
171171 "text": i18n.tr("Swipe up again to close the settings screen"),
172− "anchors.fill": demo.indicators,
172+ "anchors.fill": demo.indicators.content,
173173 });
174174 }
175175 if (d.bottomEdgeDemo) {
Components/EdgeDemoOverlay.qml+3
@@ -153,7 +153,10 @@ Showable {
153153 font.underline: true
154154
155155 MouseArea {
156+ // Make clickable area bigger than just the link because
157+ // otherwise, the edge demo will feel hard to dismiss.
156158 anchors.fill: parent
159+ anchors.margins: -units.gu(5)
157160 onClicked: overlay.doSkip()
158161 }
159162 }
Components/LazyImage.qmlnew file+172
@@ -0,0 +1,172 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Michał Sawicz <michal.sawicz@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+
23+Item {
24+ id: root
25+
26+ property url source
27+ // TODO convert into enums when available in QML
28+ property string scaleTo
29+
30+ property real initialWidth: units.gu(10)
31+ property real initialHeight: units.gu(10)
32+
33+ property alias sourceSize: image.sourceSize
34+ property alias fillMode: image.fillMode
35+ property alias asynchronous: image.asynchronous
36+ property alias cache: image.cache
37+ property alias horizontalAlignment: image.horizontalAlignment
38+ property alias verticalAlignment: image.verticalAlignment
39+
40+ state: "default"
41+
42+ onSourceChanged: {
43+ if (state === "ready") {
44+ state = "default";
45+ image.nextSource = source;
46+ } else {
47+ image.source = source;
48+ }
49+ }
50+
51+ UbuntuShape {
52+ id: placeholder
53+ objectName: "placeholder"
54+ color: "#22FFFFFF"
55+ anchors.fill: parent
56+ visible: opacity != 0
57+
58+ ActivityIndicator {
59+ id: activity
60+ anchors.centerIn: parent
61+ opacity: 0
62+ visible: opacity != 0
63+
64+ running: visible
65+ }
66+
67+ Image {
68+ id: errorImage
69+ objectName: "errorImage"
70+ anchors.centerIn: parent
71+ opacity: 0
72+ visible: opacity != 0
73+
74+ source: "graphics/close.png"
75+ sourceSize { width: units.gu(3); height: units.gu(3) }
76+ }
77+ }
78+
79+ UbuntuShape {
80+ id: shape
81+ objectName: "shape"
82+ anchors.fill: parent
83+ opacity: 0
84+ visible: opacity != 0
85+
86+ image: Image {
87+ id: image
88+ objectName: "image"
89+
90+ property url nextSource
91+
92+ width: root.scaleTo == "height" ? implicitWidth * root.height / implicitHeight : implicitWidth
93+ height: root.scaleTo == "width" ? implicitHeight * root.width / implicitWidth : implicitHeight
94+ fillMode: Image.PreserveAspectCrop
95+ asynchronous: true
96+ cache: false
97+ horizontalAlignment: Image.AlignHCenter
98+ verticalAlignment: Image.AlignVCenter
99+ sourceSize.width: root.scaleTo == "width" ? root.width : 0
100+ sourceSize.height: root.scaleTo == "height" ? root.height : 0
101+ }
102+ }
103+
104+ states: [
105+ State {
106+ name: "default"
107+ when: image.source == ""
108+ PropertyChanges { target: root; implicitWidth: root.initialWidth; implicitHeight: root.initialHeight }
109+ PropertyChanges { target: errorImage; opacity: 0 }
110+ },
111+ State {
112+ name: "loading"
113+ extend: "default"
114+ when: image.status === Image.Loading
115+ PropertyChanges { target: activity; opacity: 1 }
116+ },
117+ State {
118+ name: "ready"
119+ when: image.status === Image.Ready && image.source != ""
120+ PropertyChanges { target: root; implicitWidth: image.width; implicitHeight: image.height }
121+ PropertyChanges { target: shape; opacity: 1 }
122+ PropertyChanges { target: placeholder; opacity: 0 }
123+ },
124+ State {
125+ name: "error"
126+ extend: "default"
127+ when: image.status === Image.Error
128+ PropertyChanges { target: errorImage; opacity: 1.0 }
129+ }
130+ ]
131+
132+ transitions: [
133+ Transition {
134+ to: "ready"
135+ objectName: "readyTransition"
136+ SequentialAnimation {
137+ PropertyAction { target: shape; property: "visible" }
138+ ParallelAnimation {
139+ NumberAnimation { target: shape; property: "opacity"; easing.type: Easing.Linear }
140+ UbuntuNumberAnimation { target: root; properties: "implicitWidth,implicitHeight" }
141+ NumberAnimation {
142+ targets: [placeholder, activity, errorImage]; property: "opacity";
143+ easing.type: Easing.Linear; duration: UbuntuAnimation.SnapDuration
144+ }
145+ }
146+ }
147+ },
148+
149+ Transition {
150+ to: "*"
151+ objectName: "genericTransition"
152+ SequentialAnimation {
153+ ParallelAnimation {
154+ NumberAnimation { target: shape; property: "opacity"; easing.type: Easing.Linear }
155+ NumberAnimation {
156+ targets: [placeholder, activity, errorImage]; property: "opacity";
157+ easing.type: Easing.Linear; duration: UbuntuAnimation.SnapDuration
158+ }
159+ UbuntuNumberAnimation { target: root; properties: "implicitWidth,implicitHeight" }
160+ }
161+ PropertyAction { target: shape; property: "visible" }
162+ }
163+
164+ onRunningChanged: {
165+ if (!running && state === "default" && image.nextSource !== "") {
166+ image.source = image.nextSource;
167+ image.nextSource = "";
168+ }
169+ }
170+ }
171+ ]
172+}
Components/ResponsiveGridView.qml+1−1
@@ -67,7 +67,7 @@ Item {
6767
6868 function columnsForSpacing(spacing) {
6969 // minimum margin is half of the spacing
70− return Math.floor((parent.width - spacing/2) / (delegateWidth + spacing));
70+ return Math.max(1, Math.floor((parent.width - spacing/2) / (delegateWidth + spacing)));
7171 }
7272
7373 property real allocatableHorizontalSpace: parent.width - columns * delegateWidth
Components/VolumeControl.qml+5−20
@@ -21,37 +21,22 @@ Item {
2121 id: root
2222 objectName: "volumeControl"
2323 visible: false
24− property int volume
2524
2625 QDBusActionGroup {
2726 id: actionGroup
2827 busType: 1
29− busName: "com.canonical.settings.sound"
30− objectPath: "/com/canonical/settings/sound"
28+ busName: "com.canonical.indicator.sound"
29+ objectPath: "/com/canonical/indicator/sound"
3130
32− property variant actionObject: action("volume")
33− property variant serverVolume: actionObject.valid ? actionObject.state: 0
34− }
35−
36− Binding {
37− target: root
38− property: "volume"
39− value: actionGroup.serverVolume * 100
40− }
41−
42− onVolumeChanged: {
43− if (actionGroup.serverVolume != volume) {
44− var targetVolume = Math.min(1, Math.max(0, volume / 100));
45− actionGroup.actionObject.updateState(targetVolume);
46− }
31+ property variant actionObject: action("scroll")
4732 }
4833
4934 function volumeUp() {
50− actionGroup.actionObject.updateState(Math.min(1, volume/100 + 0.10));
35+ actionGroup.actionObject.activate(1);
5136 }
5237
5338 function volumeDown() {
54− actionGroup.actionObject.updateState(Math.max(0, volume/100 - 0.10));
39+ actionGroup.actionObject.activate(-1);
5540 }
5641
5742 Component.onCompleted: actionGroup.start()
Components/graphics/close@20.pngnew file

Binary file not shown.

Dash/Apps/AppPreview.qml+11
@@ -110,6 +110,10 @@ DashPreview {
110110 onFinished: {
111111 root.previewData.execute(progressBar.model[0].id, { })
112112 }
113+
114+ onError: {
115+ root.previewData.execute(progressBar.model[1].id, { "error": error });
116+ }
113117 }
114118
115119 }
@@ -187,12 +191,19 @@ DashPreview {
187191 ListItem.ThinDivider { }
188192
189193 AppReviews {
194+ id: appReviews
190195 objectName: "appReviews"
196+ // TODO: This should make this visible when the feature for reviews/comments is complete.
197+ visible: false
191198 anchors { left: parent.left; right: parent.right }
192199
193200 model: root.previewData.infoMap["comments"] ? root.previewData.infoMap["comments"].value : undefined
194201
195202 onSendReview: root.sendUserReview(review);
203+
204+ onEditing: {
205+ root.ensureVisible(appReviews.textArea);
206+ }
196207 }
197208 }
198209 }
Dash/Apps/AppReviews.qml+3
@@ -23,8 +23,10 @@ Column {
2323 id: root
2424
2525 property var model
26+ property alias textArea: reviewField
2627
2728 signal sendReview(string review)
29+ signal editing
2830
2931 spacing: units.gu(2)
3032 state: ""
@@ -93,6 +95,7 @@ Column {
9395 if(reviewField.focus){
9496 root.state = "editing";
9597 reviewField.selectAll();
98+ root.editing();
9699 }
97100 }
98101
Dash/DashPreview.qml+13
@@ -20,6 +20,7 @@ import Ubuntu.Components 0.1
2020Rectangle {
2121 id: root
2222
23+ property int keyboardSize: Qt.inputMethod.visible ? Qt.inputMethod.keyboardRectangle.height : 0
2324 property var previewData
2425
2526 property string title: ""
@@ -38,6 +39,14 @@ Rectangle {
3839 color: Qt.rgba(0, 0, 0, .3)
3940 clip: true
4041
42+ function ensureVisible(item) {
43+ var o = leftFlickable.mapFromItem(item, 0, 0, item.width, item.height);
44+ var keyboardY = shell.height - root.keyboardSize;
45+ if ((o.y + o.height) > keyboardY) {
46+ leftFlickable.contentY += o.y + o.height - keyboardY;
47+ }
48+ }
49+
4150 Connections {
4251 target: shell.applicationManager
4352 onMainStageFocusedApplicationChanged: {
@@ -128,12 +137,16 @@ Rectangle {
128137
129138 Flickable {
130139 id: leftFlickable
140+ objectName: "leftFlickable"
131141 anchors.top: parent.top
132142 anchors.bottom: parent.bottom
133143 width: root.narrowMode ? contentRow.width : contentRow.width * root.previewWidthRatio
134144 contentHeight: leftColumn.height
145+ anchors.bottomMargin: root.keyboardSize
135146 clip: true
136147
148+ Behavior on contentY { NumberAnimation { duration: 300 } }
149+
137150 Column {
138151 id: leftColumn
139152 objectName: "leftColumn"
Dash/GenericScopeView.qml+24−8
@@ -21,10 +21,11 @@ import "../Components/ListItems" as ListItems
2121
2222ScopeView {
2323 id: scopeView
24− property alias previewShown: previewLoader.onScreen
24+ readonly property alias previewShown: previewLoader.onScreen
2525
2626 onIsCurrentChanged: {
2727 pageHeader.resetSearch();
28+ previewLoader.open = false;
2829 }
2930
3031 onMovementStarted: categoryView.showHeader()
@@ -35,6 +36,12 @@ ScopeView {
3536 value: pageHeader.searchQuery
3637 }
3738
39+ Binding {
40+ target: pageHeader
41+ property: "searchQuery"
42+ value: scopeView.scope.searchQuery
43+ }
44+
3845 Connections {
3946 target: panel
4047 onSearchClicked: if (isCurrent) {
@@ -43,6 +50,12 @@ ScopeView {
4350 }
4451 }
4552
53+ Connections {
54+ target: scopeView.scope
55+ onShowDash: previewLoader.open = false;
56+ onHideDash: previewLoader.open = false;
57+ }
58+
4659 ScopeListView {
4760 id: categoryView
4861 anchors.fill: parent
@@ -52,13 +65,14 @@ ScopeView {
5265 onAtYEndChanged: if (atYEnd) endReached()
5366 onMovingChanged: if (moving && atYEnd) endReached()
5467
55− property int expandedIndex: -1
68+ property string expandedCategoryId: ""
5669
5770 delegate: ListItems.Base {
5871 highlightWhenPressed: false
5972
6073 readonly property bool expandable: rendererLoader.item ? rendererLoader.item.expandable : false
6174 readonly property bool filtered: rendererLoader.item ? rendererLoader.item.filter : true
75+ readonly property string category: categoryId
6276
6377 Loader {
6478 id: rendererLoader
@@ -80,7 +94,7 @@ ScopeView {
8094 }
8195 item.objectName = Qt.binding(function() { return categoryId })
8296 if (item.expandable) {
83− var shouldFilter = index != categoryView.expandedIndex;
97+ var shouldFilter = categoryId != categoryView.expandedCategoryId;
8498 if (shouldFilter != item.filter) {
8599 item.filter = shouldFilter;
86100 }
@@ -116,10 +130,10 @@ ScopeView {
116130 }
117131 Connections {
118132 target: categoryView
119− onExpandedIndexChanged: {
133+ onExpandedCategoryIdChanged: {
120134 var item = rendererLoader.item;
121135 if (item.expandable) {
122− var shouldFilter = index != categoryView.expandedIndex;
136+ var shouldFilter = categoryId != categoryView.expandedCategoryId;
123137 if (shouldFilter != item.filter) {
124138 // If the filter animation will be seen start it, otherwise, just flip the switch
125139 var shrinkingVisible = shouldFilter && y + item.collapsedHeight < categoryView.height;
@@ -150,10 +164,10 @@ ScopeView {
150164 return "";
151165 }
152166 onClicked: {
153− if (categoryView.expandedIndex != delegateIndex)
154− categoryView.expandedIndex = delegateIndex;
167+ if (categoryView.expandedCategoryId != delegate.category)
168+ categoryView.expandedCategoryId = delegate.category;
155169 else
156− categoryView.expandedIndex = -1;
170+ categoryView.expandedCategoryId = "";
157171 }
158172 }
159173 pageHeader: PageHeader {
@@ -179,6 +193,7 @@ ScopeView {
179193 case "grid": {
180194 switch (contentType) {
181195 case "video": return "Generic/GenericFilterGridPotrait.qml";
196+ case "music": return "Music/MusicFilterGrid.qml";
182197 default: return "Generic/GenericFilterGrid.qml";
183198 }
184199 }
@@ -246,6 +261,7 @@ ScopeView {
246261 }
247262
248263 Loader {
264+ objectName: "previewLoader"
249265 id: previewLoader
250266 property var previewData
251267 height: effect.bottomGapPx - effect.topGapPx
Dash/Music/MusicFilterGrid.qml+12−2
@@ -29,19 +29,29 @@ FilterGrid {
2929 readonly property int iconWidth: (width / columns) * 0.8
3030 readonly property int iconHeight: iconWidth
3131
32− signal clicked(int index)
32+ signal clicked(int index, var delegateItem, real itemY)
33+ signal pressAndHold(int index, var delegateItem, real itemY)
3334
3435 delegate: AlbumTile {
36+ id: tile
3537 objectName: "delegate" + index
3638 width: filterGrid.cellWidth
3739 height: filterGrid.cellHeight
3840 iconWidth: filterGrid.iconWidth
3941 iconHeight: filterGrid.iconHeight
42+
4043 artist: model.title
4144 album: model.comment
4245 source: model.icon
46+
4347 onClicked: {
44− filterGrid.clicked(index);
48+ var data = { model: model }
49+ filterGrid.clicked(index, data, tile.y)
50+ }
51+
52+ onPressAndHold: {
53+ var data = { model: model }
54+ filterGrid.pressAndHold(index, data, tile.y)
4555 }
4656 }
4757}
Greeter/GreeterContent.qml+1−1
@@ -47,7 +47,7 @@ MouseArea {
4747 id: wallpaper
4848 objectName: "wallpaper"
4949 anchors.fill: parent
50− fadeInFirst: false
50+ fillMode: Image.PreserveAspectCrop
5151 }
5252
5353 // See Shell.qml's backgroundSettings treatment for why we need a separate
MouseTouchAdaptor.cpp+29−12
@@ -39,24 +39,16 @@ Qt::MouseButton translateMouseButton(xcb_button_t detail)
3939} // end of anonymous namespace
4040
4141MouseTouchAdaptor::MouseTouchAdaptor()
42− : m_targetWindow(0)
43− , m_leftButtonIsPressed(false)
42+ : m_leftButtonIsPressed(false)
4443{
4544 m_touchDevice = new QTouchDevice;
4645 m_touchDevice->setType(QTouchDevice::TouchScreen);
4746 QWindowSystemInterface::registerTouchDevice(m_touchDevice);
4847}
4948
50−void MouseTouchAdaptor::setTargetWindow(QWindow *window)
51−{
52− m_targetWindow = window;
53−}
54−
5549bool MouseTouchAdaptor::nativeEventFilter(const QByteArray & eventType,
5650 void * message, long * /*result*/)
5751{
58− Q_ASSERT(m_targetWindow);
59−
6052 if (eventType != "xcb_generic_event_t") {
6153 // wrong backend.
6254 qWarning("MouseTouchAdaptor: XCB backend not in use. Adaptor inoperative!");
@@ -91,7 +83,9 @@ bool MouseTouchAdaptor::handleButtonPress(xcb_button_press_event_t *pressEvent)
9183
9284 QPoint windowPos(pressEvent->event_x, pressEvent->event_y);
9385
94− QTouchEventSequence touchEvent = QTest::touchEvent(m_targetWindow, m_touchDevice,
86+ QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(pressEvent->event));
87+
88+ QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
9589 false /* autoCommit */);
9690 touchEvent.press(0 /* touchId */, windowPos);
9791 touchEvent.commit(false /* processEvents */);
@@ -110,7 +104,9 @@ bool MouseTouchAdaptor::handleButtonRelease(xcb_button_release_event_t *releaseE
110104
111105 QPoint windowPos(releaseEvent->event_x, releaseEvent->event_y);
112106
113− QTouchEventSequence touchEvent = QTest::touchEvent(m_targetWindow, m_touchDevice,
107+ QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(releaseEvent->event));
108+
109+ QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
114110 false /* autoCommit */);
115111 touchEvent.release(0 /* touchId */, windowPos);
116112 touchEvent.commit(false /* processEvents */);
@@ -127,10 +123,31 @@ bool MouseTouchAdaptor::handleMotionNotify(xcb_motion_notify_event_t *event)
127123
128124 QPoint windowPos(event->event_x, event->event_y);
129125
130− QTouchEventSequence touchEvent = QTest::touchEvent(m_targetWindow, m_touchDevice,
126+ QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(event->event));
127+
128+ QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
131129 false /* autoCommit */);
132130 touchEvent.move(0 /* touchId */, windowPos);
133131 touchEvent.commit(false /* processEvents */);
134132
135133 return true;
136134}
135+
136+QWindow *MouseTouchAdaptor::findQWindowWithXWindowID(WId windowId)
137+{
138+ QWindowList windowList = QGuiApplication::topLevelWindows();
139+ QWindow *foundWindow = nullptr;
140+
141+ int i = 0;
142+ while (!foundWindow && i < windowList.count()) {
143+ QWindow *window = windowList[i];
144+ if (window->winId() == windowId) {
145+ foundWindow = window;
146+ } else {
147+ ++i;
148+ }
149+ }
150+
151+ Q_ASSERT(foundWindow);
152+ return foundWindow;
153+}
MouseTouchAdaptor.h+2−5
@@ -20,11 +20,11 @@
2020#define MOUSE_TOUCH_ADAPTOR_H
2121
2222#include <QtCore/QAbstractNativeEventFilter>
23+#include <QWindow>
2324#include <xcb/xcb.h>
2425
2526class QMouseEvent;
2627class QTouchDevice;
27−class QWindow;
2828
2929// Transforms QMouseEvents into single-finger QTouchEvents.
3030class MouseTouchAdaptor : public QAbstractNativeEventFilter {
@@ -32,9 +32,6 @@ class MouseTouchAdaptor : public QAbstractNativeEventFilter {
3232public:
3333 MouseTouchAdaptor();
3434
35− // The window that will receive the generated QTouchEvents
36− void setTargetWindow(QWindow *window);
37−
3835 // Filters mouse events and posts the equivalent QTouchEvents.
3936 virtual bool nativeEventFilter(const QByteArray & eventType, void *message, long *result);
4037
@@ -43,8 +40,8 @@ private:
4340 bool handleButtonPress(xcb_button_press_event_t *pressEvent);
4441 bool handleButtonRelease(xcb_button_release_event_t *releaseEvent);
4542 bool handleMotionNotify(xcb_motion_notify_event_t *event);
43+ QWindow *findQWindowWithXWindowID(WId windowId);
4644
47− QWindow *m_targetWindow;
4845 QTouchDevice *m_touchDevice;
4946 bool m_leftButtonIsPressed;
5047};
Panel/Indicators.qml+1
@@ -35,6 +35,7 @@ Showable {
3535 property bool partiallyOpened: height > panelHeight && !fullyOpened
3636 property real visualBottom: Math.max(y+height, y+indicatorRow.y+indicatorRow.height)
3737 property bool contentEnabled: true
38+ readonly property alias content: menuContent
3839
3940 // TODO: Perhaps we need a animation standard for showing/hiding? Each showable seems to
4041 // use its own values. Need to ask design about this.
Panel/IndicatorsDataModel.qml−4
@@ -27,10 +27,6 @@ Indicators.IndicatorsModel {
2727 Component.onCompleted: load()
2828
2929 indicatorData : {
30− 'indicator-messages' : {
31− 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/MessagingIndicatorWidget.qml',
32− 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/MessagingIndicatorPage.qml'
33− },
3430 'indicator-network' : {
3531 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/NetworkIndicatorPage2.qml'
3632 },
Panel/MenuContent.qml+12−2
@@ -109,7 +109,7 @@ MainView {
109109 source: pageSource
110110 asynchronous: true
111111
112− property bool contentActive: content.__contentActive
112+ property bool contentActive: content.__contentActive && menuActivator.content[index].active
113113
114114 onContentActiveChanged: {
115115 if (contentActive && item) {
@@ -152,6 +152,16 @@ MainView {
152152 id: contentReleaseTimer
153153
154154 interval: contentReleaseInterval
155− onTriggered: content.__contentActive = false
155+ onTriggered: {
156+ content.__contentActive = false;
157+ menuActivator.clear();
158+ }
159+ }
160+
161+ Indicators.MenuContentActivator {
162+ id: menuActivator
163+ running: content.__contentActive
164+ baseIndex: content.currentMenuIndex
165+ count: indicatorsModel.count
156166 }
157167}
Shell.qml+22−11
@@ -23,6 +23,7 @@ import Ubuntu.Gestures 0.1
2323import Unity.Launcher 0.1
2424import LightDM 0.1 as LightDM
2525import Powerd 0.1
26+import SessionBroadcast 0.1
2627import "Dash"
2728import "Greeter"
2829import "Launcher"
@@ -83,6 +84,8 @@ FocusScope {
8384
8485 readonly property bool applicationFocused: !!applicationManager.mainStageFocusedApplication
8586 || !!applicationManager.sideStageFocusedApplication
87+ // Used for autopilot testing.
88+ readonly property string currentFocusedAppId: ApplicationManager.focusedApplicationId
8689
8790 readonly property bool fullscreenMode: {
8891 if (greeter.shown || lockscreen.shown) {
@@ -195,6 +198,7 @@ FocusScope {
195198
196199 anchors.fill: parent
197200 source: shell.background
201+ fillMode: Image.PreserveAspectCrop
198202 }
199203
200204 Rectangle {
@@ -545,6 +549,17 @@ FocusScope {
545549 }
546550 }
547551
552+ function showHome() {
553+ greeter.hide()
554+ // Animate if moving between application and dash
555+ if (!stages.shown) {
556+ dash.setCurrentScope("home.scope", true, false)
557+ } else {
558+ dash.setCurrentScope("home.scope", false, false)
559+ }
560+ stages.hide()
561+ }
562+
548563 Item {
549564 id: overlay
550565
@@ -610,7 +625,7 @@ FocusScope {
610625 Bottombar {
611626 theHud: hud
612627 anchors.fill: parent
613− enabled: !panel.indicators.shown
628+ enabled: hud.available
614629 applicationIsOnForeground: applicationFocused
615630 }
616631
@@ -632,16 +647,7 @@ FocusScope {
632647 width: parent.width
633648 dragAreaWidth: shell.edgeSize
634649 available: (!greeter.shown || greeter.narrowMode) && edgeDemo.launcherEnabled
635− onDashItemSelected: {
636− greeter.hide()
637− // Animate if moving between application and dash
638− if (!stages.shown) {
639− dash.setCurrentScope("home.scope", true, false)
640− } else {
641− dash.setCurrentScope("home.scope", false, false)
642− }
643− stages.hide();
644− }
650+ onDashItemSelected: showHome()
645651 onDash: {
646652 if (stages.shown) {
647653 dash.setCurrentScope("applications.scope", true, false)
@@ -749,4 +755,9 @@ FocusScope {
749755 indicators: panel.indicators
750756 underlay: underlay
751757 }
758+
759+ Connections {
760+ target: SessionBroadcast
761+ onShowHome: showHome()
762+ }
752763}
debian/changelog+123
@@ -1,3 +1,126 @@
1+unity8 (7.81.3+13.10.20130927.3-0ubuntu1) saucy; urgency=low
2+
3+ [ Michal Hruby ]
4+ * Correctly handle image URI scheme in results.
5+
6+ [ Michał Sawicz ]
7+ * Make SHOW_DASH and HIDE_DASH close the current preview. (LP:
8+ #1231404)
9+ * Add a LazyImage component that shows an activity spinner for long-
10+ loading images and handles aspect ratio properly.
11+ * Fix Qt 5.1 FTBFS and suppress some build warnings.
12+
13+ [ Albert Astals ]
14+ * Make sure we always have least have one column in the gridview. (LP:
15+ #1225391)
16+ * LVWPH: Make sure we always overshoot vertically. (LP: #1229851)
17+ * Remember the expanded categoryId and not the expanded index The
18+ index can change on search, and we still want to maintain it
19+ expanded in that case. (LP: #1230216)
20+ * Fix showHeader in an edge case of notShownByItsOwn Not all the tests
21+ i've added fail without the code fix, but i've added them just to be
22+ more covered . (LP: #1230187)
23+
24+ [ Diego Sarmentero ]
25+ * Handling error signal from the DownloadTracker plugin (BUG:
26+ #1229744). (LP: #1229744)
27+ * Remove "Reviews and Comments" section from Application Preview until
28+ the feature is ready (BUG: #1226632) - Detect when the keyboard is
29+ being shown to allow the user to scroll the Preview even more if
30+ necessary to interact with the components at the bottom of that
31+ preview, and don't leave those components obscured behind the
32+ keyboard (BUG: #1226638). (LP: #1226632, #1224717, #1226638)
33+
34+ [ Nick Dedekind ]
35+ * Brought messaging indicator inline with UnityMenuModel &
36+ UnityMenuAction. (LP: #1217676, #1217678)
37+
38+ [ Pawel Stolowski ]
39+ * Support canned search queries returned by Home Scope.
40+ * Cancel previous actions and previews on new activation / preview.
41+ Expose previewed data row in Preview object.
42+
43+ [ Michael Terry ]
44+ * Only enable the Bottombar when the HUD is available. (LP: #1220306)
45+ * Increase the "Skip intro" clickable area, making dismissing the edge
46+ demo intro feel more natural. (LP: #1220632)
47+
48+ [ Michael Zanetti ]
49+ * drop our CrossFadeImage in favor of the SDK one. (LP: #1227783)
50+
51+ [ Ubuntu daily release ]
52+ * Automatic snapshot from revision 358
53+
54+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Fri, 27 Sep 2013 14:13:22 +0000
55+
56+unity8 (7.81.3+13.10.20130924.2-0ubuntu1) saucy; urgency=low
57+
58+ [ Michal Hruby ]
59+ * Fix the signal prototypes on music grid renderer. (LP: #1228390)
60+
61+ [ Michael Zanetti ]
62+ * use less auto variables, align coding style, constify and Qt'ify API
63+ in AccountsService plugin.
64+
65+ [ Nick Dedekind ]
66+ * Re-enable MenuContentActivator in Indicators.
67+
68+ [ Albert Astals ]
69+ * LVWPH: Update the section header on list change events.
70+
71+ [ Pawel Stolowski ]
72+ * Check results model ptr returned by GetResultsFromCategory method
73+ from UnityCore. (LP: #1228097, #1211595)
74+
75+ [ Ubuntu daily release ]
76+ * Automatic snapshot from revision 340
77+
78+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 24 Sep 2013 14:40:01 +0000
79+
80+unity8 (7.81.3+13.10.20130919.3-0ubuntu1) saucy; urgency=low
81+
82+ [ Michal Hruby ]
83+ * Add support for music grid renderer to GenericScopeView.
84+
85+ [ Nick Dedekind ]
86+ * Fixed the removal of messaging widget due to incompatible action
87+ state. (LP: #1225017)
88+
89+ [ Christopher Lee ]
90+ * Addition of initial autopilot tests for the application lifecycle.
91+
92+ [ Lars Uebernickel ]
93+ * VolumeControl: use action of the new indicator indicator-sound
94+ recently gained an action to increase and decrease the volume. This
95+ patch makes use of that to get rid of a bus round trip (to get the
96+ current volume) and a race (when the volume gets set between
97+ fetching the current volume and setting the new volume). (LP:
98+ #1219057)
99+
100+ [ Michael Terry ]
101+ * When AccountsService.backgroundFile is unset/invalid, have the
102+ greeter fall back to whatever the shell background is.
103+ * Add a tiny SessionBroadcast plugin that listens to unity-greeter-
104+ session-broadcast for the ShowHome signal.
105+
106+ [ Daniel d'Andrada ]
107+ * Remove obsolete, unused graphics.
108+ * Make MouseTouchAdaptor work with multiple QWindows.
109+
110+ [ Michael Zanetti ]
111+ * change how icons are searched a) try to find it the Icon as is b)
112+ prepend with Path if a Path variable is given c) fall back to the
113+ image://theme/ with just the icon name . (LP: #1225186)
114+ * fix an issue with removing a running app from the launcher and
115+ always store pinning to the config.
116+ * collapse any open preview when programmatically switching current
117+ dash index. (LP: #1221137)
118+
119+ [ Ubuntu daily release ]
120+ * Automatic snapshot from revision 333
121+
122+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Thu, 19 Sep 2013 15:15:07 +0000
123+
1124unity8 (7.81.3+13.10.20130916-0ubuntu1) saucy; urgency=low
2125
3126 [ Michael Zanetti ]
debian/control+1−1
@@ -21,7 +21,7 @@ Build-Depends: cmake,
2121 libqt5v8-5-private-dev,
2222 libsigc++-2.0-dev,
2323 libunity-api-dev (>= 7.80.3),
24− libunity-core-6.0-dev (<< 7.80),
24+ libunity-core-6.0-dev (>= 7.1.1),
2525 libunity-dev (>= 7.0.12),
2626 libunity-mir-dev,
2727 libunity-scopes-json-def-phone,
debian/unity8-private.install+1
@@ -3,6 +3,7 @@ usr/lib/*/unity8/qml/HudClient
33usr/lib/*/unity8/qml/LightDM
44usr/lib/*/unity8/qml/ListViewWithPageHeader
55usr/lib/*/unity8/qml/Powerd
6+usr/lib/*/unity8/qml/SessionBroadcast
67usr/lib/*/unity8/qml/Ubuntu
78usr/lib/*/unity8/qml/Unity
89usr/lib/*/unity8/qml/Utils
debian/unity8.install−1
@@ -13,4 +13,3 @@ usr/share/unity8/Panel
1313usr/share/unity8/Shell.qml
1414usr/share/unity8/SideStage
1515usr/share/unity8/graphics
16−usr/share/unity8/unity/indicators/*
main.cpp−1
@@ -144,7 +144,6 @@ int startShell(int argc, const char** argv, void* server)
144144 MouseTouchAdaptor *mouseTouchAdaptor = 0;
145145 if (args.contains(QLatin1String("-mousetouch"))) {
146146 mouseTouchAdaptor = new MouseTouchAdaptor;
147− mouseTouchAdaptor->setTargetWindow(view);
148147 application->installNativeEventFilter(mouseTouchAdaptor);
149148 }
150149
plugins/AccountsService/AccountsService.cpp+3−3
@@ -32,7 +32,7 @@ AccountsService::AccountsService(QObject* parent)
3232 this, SLOT(maybeChanged(const QString &)));
3333}
3434
35−QString AccountsService::getUser()
35+QString AccountsService::user() const
3636{
3737 return m_user;
3838}
@@ -46,7 +46,7 @@ void AccountsService::setUser(const QString &user)
4646 updateBackgroundFile();
4747}
4848
49−bool AccountsService::getDemoEdges()
49+bool AccountsService::demoEdges() const
5050{
5151 return m_demoEdges;
5252}
@@ -57,7 +57,7 @@ void AccountsService::setDemoEdges(bool demoEdges)
5757 m_service->setUserProperty(m_user, "com.canonical.unity.AccountsService", "demo-edges", demoEdges);
5858}
5959
60−QString AccountsService::getBackgroundFile()
60+QString AccountsService::backgroundFile() const
6161{
6262 return m_backgroundFile;
6363}
plugins/AccountsService/AccountsService.h+6−6
@@ -28,25 +28,25 @@ class AccountsService: public QObject
2828{
2929 Q_OBJECT
3030 Q_PROPERTY (QString user
31− READ getUser
31+ READ user
3232 WRITE setUser
3333 NOTIFY userChanged)
3434 Q_PROPERTY (bool demoEdges
35− READ getDemoEdges
35+ READ demoEdges
3636 WRITE setDemoEdges
3737 NOTIFY demoEdgesChanged)
3838 Q_PROPERTY (QString backgroundFile
39− READ getBackgroundFile
39+ READ backgroundFile
4040 NOTIFY backgroundFileChanged)
4141
4242public:
4343 explicit AccountsService(QObject *parent = 0);
4444
45− QString getUser();
45+ QString user() const;
4646 void setUser(const QString &user);
47− bool getDemoEdges();
47+ bool demoEdges() const;
4848 void setDemoEdges(bool demoEdges);
49− QString getBackgroundFile();
49+ QString backgroundFile() const;
5050
5151Q_SIGNALS:
5252 void userChanged();
plugins/AccountsService/AccountsServiceDBusAdaptor.cpp+15−15
@@ -24,13 +24,13 @@
2424
2525AccountsServiceDBusAdaptor::AccountsServiceDBusAdaptor(QObject* parent)
2626 : QObject(parent),
27− accounts_manager(NULL),
28− users()
27+ m_accountsManager(NULL),
28+ m_users()
2929{
30− auto connection = QDBusConnection::SM_BUSNAME();
31− auto interface = connection.interface();
30+ QDBusConnection connection = QDBusConnection::SM_BUSNAME();
31+ QDBusConnectionInterface *interface = connection.interface();
3232 interface->startService("org.freedesktop.Accounts");
33− accounts_manager = new QDBusInterface("org.freedesktop.Accounts",
33+ m_accountsManager = new QDBusInterface("org.freedesktop.Accounts",
3434 "/org/freedesktop/Accounts",
3535 "org.freedesktop.Accounts",
3636 connection, this);
@@ -38,9 +38,9 @@ AccountsServiceDBusAdaptor::AccountsServiceDBusAdaptor(QObject* parent)
3838
3939QVariant AccountsServiceDBusAdaptor::getUserProperty(const QString &user, const QString &interface, const QString &property)
4040{
41− auto iface = getUserInterface(user);
41+ QDBusInterface *iface = getUserInterface(user);
4242 if (iface != nullptr && iface->isValid()) {
43− auto answer = iface->call("Get", interface, property);
43+ QDBusMessage answer = iface->call("Get", interface, property);
4444 if (answer.type() == QDBusMessage::ReplyMessage) {
4545 return answer.arguments()[0].value<QDBusVariant>().variant();
4646 }
@@ -50,7 +50,7 @@ QVariant AccountsServiceDBusAdaptor::getUserProperty(const QString &user, const
5050
5151void AccountsServiceDBusAdaptor::setUserProperty(const QString &user, const QString &interface, const QString &property, const QVariant &value)
5252{
53− auto iface = getUserInterface(user);
53+ QDBusInterface *iface = getUserInterface(user);
5454 if (iface != nullptr && iface->isValid()) {
5555 // The value needs to be carefully wrapped
5656 iface->call("Set", interface, property, QVariant::fromValue(QDBusVariant(value)));
@@ -76,7 +76,7 @@ void AccountsServiceDBusAdaptor::maybeChangedSlot()
7676QString AccountsServiceDBusAdaptor::getUserForPath(const QString &path)
7777{
7878 QMap<QString, QDBusInterface *>::const_iterator i;
79− for (i = users.constBegin(); i != users.constEnd(); ++i) {
79+ for (i = m_users.constBegin(); i != m_users.constEnd(); ++i) {
8080 if (i.value()->path() == path) {
8181 return i.key();
8282 }
@@ -86,16 +86,16 @@ QString AccountsServiceDBusAdaptor::getUserForPath(const QString &path)
8686
8787QDBusInterface *AccountsServiceDBusAdaptor::getUserInterface(const QString &user)
8888{
89− auto iface = users.value(user);
90− if (iface == nullptr && accounts_manager->isValid()) {
91− auto answer = accounts_manager->call("FindUserByName", user);
89+ QDBusInterface *iface = m_users.value(user);
90+ if (iface == nullptr && m_accountsManager->isValid()) {
91+ QDBusMessage answer = m_accountsManager->call("FindUserByName", user);
9292 if (answer.type() == QDBusMessage::ReplyMessage) {
93− auto path = answer.arguments()[0].value<QDBusObjectPath>().path();
93+ QString path = answer.arguments()[0].value<QDBusObjectPath>().path();
9494
9595 iface = new QDBusInterface("org.freedesktop.Accounts",
9696 path,
9797 "org.freedesktop.DBus.Properties",
98− accounts_manager->connection(), this);
98+ m_accountsManager->connection(), this);
9999
100100 // With its own pre-defined properties, AccountsService is oddly
101101 // close-lipped. It won't send out proper DBus.Properties notices,
@@ -119,7 +119,7 @@ QDBusInterface *AccountsServiceDBusAdaptor::getUserInterface(const QString &user
119119 this,
120120 SLOT(propertiesChangedSlot(QString, QVariantMap, QStringList)));
121121
122− users.insert(user, iface);
122+ m_users.insert(user, iface);
123123 }
124124 }
125125 return iface;
plugins/AccountsService/AccountsServiceDBusAdaptor.h+2−2
@@ -47,8 +47,8 @@ private:
4747 QDBusInterface *getUserInterface(const QString &user);
4848 QString getUserForPath(const QString &path);
4949
50− QDBusInterface *accounts_manager;
51− QMap<QString, QDBusInterface *> users;
50+ QDBusInterface *m_accountsManager;
51+ QMap<QString, QDBusInterface *> m_users;
5252};
5353
5454#endif
plugins/CMakeLists.txt+1
@@ -3,6 +3,7 @@ add_subdirectory(HudClient)
33add_subdirectory(LightDM)
44add_subdirectory(ListViewWithPageHeader)
55add_subdirectory(Powerd)
6+add_subdirectory(SessionBroadcast)
67add_subdirectory(Ubuntu)
78add_subdirectory(Unity)
89add_subdirectory(Utils)
plugins/ListViewWithPageHeader/listviewwithpageheader.cpp+20−1
@@ -170,6 +170,8 @@ ListViewWithPageHeader::ListViewWithPageHeader()
170170 connect(this, SIGNAL(contentHeightChanged()), this, SLOT(onContentHeightChanged()));
171171 connect(this, SIGNAL(heightChanged()), this, SLOT(onHeightChanged()));
172172 connect(m_contentYAnimation, SIGNAL(stopped()), this, SLOT(onShowHeaderAnimationFinished()));
173+
174+ setFlickableDirection(VerticalFlick);
173175}
174176
175177ListViewWithPageHeader::~ListViewWithPageHeader()
@@ -199,6 +201,7 @@ void ListViewWithPageHeader::setModel(QAbstractItemModel *model)
199201 connect(m_delegateModel, SIGNAL(modelUpdated(QQmlChangeSet,bool)), this, SLOT(onModelUpdated(QQmlChangeSet,bool)));
200202#endif
201203 Q_EMIT modelChanged();
204+ polish();
202205 // TODO?
203206// Q_EMIT contentHeightChanged();
204207// Q_EMIT contentYChanged();
@@ -482,7 +485,7 @@ void ListViewWithPageHeader::viewportMoved(Qt::Orientations orient)
482485 // or the header is partially shown and we are not doing a maximizeVisibleArea either
483486 const bool scrolledUp = m_previousContentY > contentY();
484487 const bool notRebounding = contentY() + height() < contentHeight();
485− const bool notShownByItsOwn = contentY() + diff > m_headerItem->y() + m_headerItem->height();
488+ const bool notShownByItsOwn = contentY() + diff >= m_headerItem->y() + m_headerItem->height();
486489 const bool maximizeVisibleAreaRunning = m_contentYAnimation->isRunning() && contentYAnimationType == ContentYAnimationMaximizeVisibleArea;
487490
488491 if (!scrolledUp && contentY() == -m_minYExtent) {
@@ -1006,6 +1009,22 @@ void ListViewWithPageHeader::onModelUpdated(const QQmlChangeSet &changeSet, bool
10061009 }
10071010 }
10081011
1012+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
1013+ Q_FOREACH(const QQuickChangeSet::Change &change, changeSet.changes()) {
1014+#else
1015+ Q_FOREACH(const QQmlChangeSet::Change &change, changeSet.changes()) {
1016+#endif
1017+// qDebug() << "ListViewWithPageHeader::onModelUpdated Change" << change.index << change.count;
1018+ for (int i = change.index; i < change.count; ++i) {
1019+ ListItem *item = itemAtIndex(i);
1020+ if (item && item->m_sectionItem) {
1021+ QQmlContext *context = QQmlEngine::contextForObject(item->m_sectionItem)->parentContext();
1022+ const QString sectionText = m_delegateModel->stringValue(i, m_sectionProperty);
1023+ context->setContextProperty(QLatin1String("section"), sectionText);
1024+ }
1025+ }
1026+ }
1027+
10091028 if (m_firstVisibleIndex != oldFirstVisibleIndex) {
10101029 adjustMinYExtent();
10111030 }
plugins/ListViewWithPageHeader/listviewwithpageheader.h+1
@@ -63,6 +63,7 @@ class ListViewWithPageHeader : public QQuickFlickable, public QQuickItemChangeLi
6363
6464 friend class ListViewWithPageHeaderTest;
6565 friend class ListViewWithPageHeaderTestSection;
66+ friend class ListViewWithPageHeaderTestExternalModel;
6667
6768public:
6869 ListViewWithPageHeader();
plugins/SessionBroadcast/CMakeLists.txtnew file+13
@@ -0,0 +1,13 @@
1+include(Plugins)
2+
3+add_definitions(-DSM_BUSNAME=systemBus)
4+
5+add_library(SessionBroadcast-qml MODULE
6+ SessionBroadcast.cpp
7+ plugin.cpp
8+ )
9+
10+qt5_use_modules(SessionBroadcast-qml DBus Qml)
11+
12+export_qmlfiles(SessionBroadcast SessionBroadcast)
13+export_qmlplugin(SessionBroadcast 0.1 SessionBroadcast TARGETS SessionBroadcast-qml)
plugins/SessionBroadcast/SessionBroadcast.cppnew 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+ * Author: Michael Terry <michael.terry@canonical.com>
17+ */
18+
19+#include "SessionBroadcast.h"
20+#include <QDBusConnection>
21+
22+SessionBroadcast::SessionBroadcast(QObject* parent)
23+ : QObject(parent)
24+{
25+ auto connection = QDBusConnection::SM_BUSNAME();
26+
27+ connection.connect("com.canonical.Unity.Greeter.Broadcast",
28+ "/com/canonical/Unity/Greeter/Broadcast",
29+ "com.canonical.Unity.Greeter.Broadcast",
30+ "ShowHome",
31+ this,
32+ SLOT(onShowHome(const QString &)));
33+}
34+
35+void SessionBroadcast::onShowHome(const QString &username)
36+{
37+ // Only listen to requests meant for us
38+ if (username == qgetenv("USER")) {
39+ Q_EMIT showHome();
40+ }
41+}
plugins/SessionBroadcast/SessionBroadcast.hnew 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+ * Authors: Michael Terry <michael.terry@canonical.com>
17+ */
18+
19+#ifndef UNITY_SESSIONBROADCAST_H
20+#define UNITY_SESSIONBROADCAST_H
21+
22+#include <QObject>
23+#include <QString>
24+
25+class QDBusInterface;
26+
27+class SessionBroadcast: public QObject
28+{
29+ Q_OBJECT
30+
31+public:
32+ explicit SessionBroadcast(QObject *parent = 0);
33+
34+Q_SIGNALS:
35+ void showHome();
36+
37+private Q_SLOTS:
38+ void onShowHome(const QString &username);
39+};
40+
41+#endif
plugins/SessionBroadcast/plugin.cppnew file+35
@@ -0,0 +1,35 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors: Michael Terry <michael.terry@canonical.com>
17+ */
18+
19+#include "plugin.h"
20+#include "SessionBroadcast.h"
21+
22+#include <QtQml>
23+
24+static QObject *broadcast_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
25+{
26+ Q_UNUSED(engine)
27+ Q_UNUSED(scriptEngine)
28+ return new SessionBroadcast();
29+}
30+
31+void SessionBroadcastPlugin::registerTypes(const char *uri)
32+{
33+ Q_ASSERT(uri == QLatin1String("SessionBroadcast"));
34+ qmlRegisterSingletonType<SessionBroadcast>(uri, 0, 1, "SessionBroadcast", broadcast_provider);
35+}
plugins/SessionBroadcast/plugin.hnew file+33
@@ -0,0 +1,33 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors: Michael Terry <michael.terry@canonical.com>
17+ */
18+
19+#ifndef UNITY_SESSIONBROADCAST_PLUGIN_H
20+#define UNITY_SESSIONBROADCAST_PLUGIN_H
21+
22+#include <QQmlExtensionPlugin>
23+
24+class SessionBroadcastPlugin : 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/SessionBroadcast/qmldirnew file+3
@@ -0,0 +1,3 @@
1+module SessionBroadcast
2+plugin SessionBroadcast-qml
3+typeinfo plugin.qmltypes
plugins/Unity/CMakeLists.txt+1
@@ -43,6 +43,7 @@ set(QMLPLUGIN_SRC
4343 preview.cpp
4444 previewaction.cpp
4545 previewinfohint.cpp
46+ result.cpp
4647 showallfilteroption.cpp
4748 signalslist.cpp
4849 socialpreview.cpp
plugins/Unity/Indicators/CMakeLists.txt+1
@@ -12,6 +12,7 @@ find_package(Qt5Core REQUIRED)
1212find_package(Qt5Quick REQUIRED)
1313
1414add_subdirectory(qml)
15+add_subdirectory(Messaging)
1516add_subdirectory(Network)
1617
1718include_directories(
plugins/Unity/IndicatorsLegacy/Messaging/CMakeLists.txt → plugins/Unity/Indicators/Messaging/CMakeLists.txtrenamed

The content is the same.

plugins/Unity/IndicatorsLegacy/Messaging/qml/ActionButton.qml → plugins/Unity/Indicators/Messaging/qml/ActionButton.qmlrenamed

The content is the same.

plugins/Unity/IndicatorsLegacy/Messaging/qml/ActionTextField.qml → plugins/Unity/Indicators/Messaging/qml/ActionTextField.qmlrenamed+10−7
@@ -22,11 +22,12 @@ import QtQuick 2.0
2222import Ubuntu.Components 0.1
2323
2424Item {
25− property alias actionGroup: sendButton.actionGroup
26− property alias action: sendButton.action
27−
25+ id: textField
2826 property alias text: replyField.text
2927 property alias buttonText: sendButton.text
28+ property bool activateEnabled: false
29+
30+ signal activate(var value)
3031
3132 TextField {
3233 id: replyField
@@ -50,17 +51,19 @@ Item {
5051 }
5152 }
5253
53− ActionButton {
54+ Button {
5455 id: sendButton
55−
56− actionParameter: replyField.text
5756 anchors {
5857 top: parent.top
5958 bottom: parent.bottom
6059 right: parent.right
6160 }
6261 width: units.gu(9)
63− enabled: replyField.text !== ""
62+ enabled: replyField.text !== "" && textField.activateEnabled
6463 color: enabled ? "#c94212" : "#bababa"
64+
65+ onClicked: {
66+ textField.activate(replyField.text);
67+ }
6568 }
6669}
plugins/Unity/Indicators/Messaging/qml/CMakeLists.txtnew file+5
@@ -0,0 +1,5 @@
1+# export_qmlfiles macro
2+include(Plugins)
3+
4+# export the qmldir, *.qml files.
5+export_qmlfiles(Unity.Indicators.Messaging Unity/Indicators/Messaging)
plugins/Unity/IndicatorsLegacy/Messaging/qml/GroupedMessage.qml → plugins/Unity/Indicators/Messaging/qml/GroupedMessage.qmlrenamed+13−18
@@ -20,20 +20,19 @@
2020
2121import QtQuick 2.0
2222import Ubuntu.Components 0.1
23−import Unity.IndicatorsLegacy 0.1 as Indicators
23+import Unity.Indicators 0.1 as Indicators
2424
25−Indicators.BasicMenuItem {
25+Indicators.BaseMenuItem {
2626 id: groupedMessage
27+
28+ property alias title: __title.text
2729 property alias count: label.text
30+ property string appIcon: "qrc:/indicators/artwork/messaging/default_app.svg"
2831
29− color: "#221e1b"
30− implicitHeight: units.gu(10)
32+ signal activateApp()
33+ signal dismiss()
3134
32− Indicators.MenuAction {
33− id: menuAction
34− actionGroup: groupedMessage.actionGroup
35− action: menu ? menu.action : ""
36− }
35+ implicitHeight: units.gu(10)
3736
3837 Row {
3938 anchors.fill: parent
@@ -44,17 +43,17 @@ Indicators.BasicMenuItem {
4443 height: units.gu(6)
4544 width: units.gu(6)
4645 image: Image {
47− source: menu && (menu.extra.canonical_icon.length > 0) ? "image://theme/" + encodeURI(menu.extra.canonical_icon) : "qrc:/indicators/artwork/messaging/default_app.svg"
46+ source: groupedMessage.appIcon
4847 fillMode: Image.PreserveAspectFit
4948 }
5049 }
5150
5251 Label {
52+ id: __title
5353 anchors.verticalCenter: parent.verticalCenter
5454 color: "#e8e1d0"
5555 font.weight: Font.DemiBold
5656 fontSize: "medium"
57− text: menu && menu.label ? menu.label : ""
5857 }
5958
6059 Label {
@@ -65,7 +64,7 @@ Indicators.BasicMenuItem {
6564 color: "#e8e1d0"
6665 font.weight: Font.DemiBold
6766 fontSize: "medium"
68− text: menuAction.valid ? menuAction.state[0] : "0"
67+ text: "0"
6968 }
7069 }
7170
@@ -82,15 +81,11 @@ Indicators.BasicMenuItem {
8281 MouseArea {
8382 anchors.fill: parent
8483 onClicked: {
85− if (menuAction.valid) {
86− menuAction.activate(true);
87− }
84+ groupedMessage.activateApp();
8885 }
8986 }
9087
9188 onItemRemoved: {
92− if (menuAction.valid) {
93− menuAction.activate(false);
94− }
89+ groupedMessage.dismiss();
9590 }
9691}
plugins/Unity/IndicatorsLegacy/Messaging/qml/HeroMessage.qml → plugins/Unity/Indicators/Messaging/qml/HeroMessage.qmlrenamed+25−22
@@ -20,25 +20,30 @@
2020
2121import QtQuick 2.0
2222import Ubuntu.Components 0.1
23−import Unity.IndicatorsLegacy 0.1 as Indicators
23+import Unity.Indicators 0.1 as Indicators
2424
25−Indicators.BasicMenuItem {
25+Indicators.BaseMenuItem {
2626 id: heroMessage
2727
28− property variant actionsDescription: null
2928 property alias heroMessageHeader: __heroMessageHeader
3029 property real collapsedHeight: heroMessageHeader.y + heroMessageHeader.bodyBottom + units.gu(2)
3130 property real expandedHeight: collapsedHeight
3231
33− color: "#221e1c"
32+ property alias avatar: __heroMessageHeader.avatar
33+ property alias appIcon: __heroMessageHeader.icon
34+
35+ signal activateApp
36+ signal dismiss
3437
3538 removable: state !== "expanded"
3639 implicitHeight: collapsedHeight
3740
38− Indicators.MenuAction {
39− id: menuAction
40− actionGroup: heroMessage.actionGroup
41− action: menu ? menu.action : ""
41+ Rectangle {
42+ id: background
43+ property real alpha: 0.0
44+ anchors.fill: parent
45+ color: Qt.rgba(1.0, 1.0, 1.0, alpha)
46+ z: -1
4247 }
4348
4449 HeroMessageHeader {
@@ -48,25 +53,22 @@ Indicators.BasicMenuItem {
4853 anchors.left: parent.left
4954 anchors.right: parent.right
5055
51− avatar: menu && (menu.extra.canonical_icon.length > 0) ? "image://theme/" + encodeURI(menu.extra.canonical_icon) : "qrc:/indicators/artwork/messaging/default_contact.png"
52− icon: menu && (menu.extra.canonical_app_icon.length > 0) ? "image://theme/" + encodeURI(menu.extra.canonical_app_icon) : ""
56+ avatar: "qrc:/indicators/artwork/messaging/default_contact.png"
5357 appIcon: icon
5458
5559 state: heroMessage.state
5660
5761 onAppIconClicked: {
58− if (menuAction.valid) {
59− deactivateMenu();
60− action.activate(true);
61− }
62+ deselectMenu();
63+ heroMessage.activateApp();
6264 }
6365 }
6466
6567 onClicked: {
66− if (menuActivated) {
67− deactivateMenu();
68+ if (menuSelected) {
69+ deselectMenu();
6870 } else {
69− activateMenu();
71+ selectMenu();
7072 }
7173 }
7274
@@ -84,13 +86,16 @@ Indicators.BasicMenuItem {
8486
8587 states: State {
8688 name: "expanded"
87− when: menuActivated
89+ when: menuSelected
8890
8991 PropertyChanges {
9092 target: heroMessage
91− color: "#333130"
9293 implicitHeight: heroMessage.expandedHeight
9394 }
95+ PropertyChanges {
96+ target: background
97+ alpha: 0.05
98+ }
9499 PropertyChanges {
95100 target: __topHLine
96101 opacity: 0.0
@@ -113,8 +118,6 @@ Indicators.BasicMenuItem {
113118 }
114119
115120 onItemRemoved: {
116− if (menuAction.valid) {
117− menuAction.activate(false);
118− }
121+ heroMessage.dismiss();
119122 }
120123}
plugins/Unity/IndicatorsLegacy/Messaging/qml/HeroMessageHeader.qml → plugins/Unity/Indicators/Messaging/qml/HeroMessageHeader.qmlrenamed

The content is the same.

plugins/Unity/Indicators/Messaging/qml/MessageMenuItemFactory.qmlnew file+180
@@ -0,0 +1,180 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Renato Araujo Oliveira Filho <renato@canonical.com>
18+ * Olivier Tilloy <olivier.tilloy@canonical.com>
19+ */
20+
21+import QtQuick 2.0
22+import Ubuntu.Components 0.1
23+import Unity.Indicators 0.1 as Indicators
24+import QMenuModel 0.1 as QMenuModel
25+import "utils.js" as Utils
26+
27+Indicators.BaseMenuItem {
28+ id: menuItem
29+ property var actionsDescription: menu ? menu.ext.xCanonicalMessageActions : undefined
30+
31+ implicitHeight: contents.status == Loader.Ready ? contents.item.implicitHeight : 0
32+
33+ property var model: null
34+
35+ Loader {
36+ id: contents
37+ anchors.fill: parent
38+
39+ sourceComponent: loadMessage(actionsDescription);
40+
41+ // Binding all properties for the item, to make sure that any change in the
42+ // property will be propagated to the contents.item at any time
43+ Binding {
44+ target: contents.item
45+ property: "menuSelected"
46+ value: menuSelected
47+ when: (contents.status == Loader.Ready)
48+ }
49+
50+ Binding {
51+ target: contents.item
52+ property: "menu"
53+ value: menu
54+ when: (contents.status == Loader.Ready)
55+ }
56+
57+ Connections {
58+ target: contents.item ? contents.item : null
59+ onSelectMenu: selectMenu()
60+ onDeselectMenu: deselectMenu()
61+ }
62+
63+ Component {
64+ id: simpleTextMessage
65+ SimpleTextMessage {
66+ // text
67+ title: menu && menu.label ? menu.label : ""
68+ time: menu ? Utils.formatDate(menu.ext.xCanonicalTime) : ""
69+ message: menu && menu.ext.xCanonicalText ? menu.ext.xCanonicalText : ""
70+ // icons
71+ avatar: menu && menu.ext.icon !== undefined ? menu.ext.icon : "qrc:/indicators/artwork/messaging/default_contact.png"
72+ appIcon: menu && menu.ext.xCanonicalAppIcon !== undefined ? menu.ext.xCanonicalAppIcon : "qrc:/indicators/artwork/messaging/default_app.svg"
73+
74+ onActivateApp: {
75+ menuItem.model.activate(modelIndex, true);
76+ }
77+ onDismiss: {
78+ menuItem.model.activate(modelIndex, false);
79+ }
80+ }
81+ }
82+ Component {
83+ id: textMessage
84+ TextMessage {
85+ property var replyAction: QMenuModel.UnityMenuAction {
86+ model: menuItem.model
87+ index: modelIndex
88+ name: menu && actionsDescription[0].name ? actionsDescription[0].name : ""
89+ }
90+
91+ // text
92+ title: menu && menu.label ? menu.label : ""
93+ time: menu ? Utils.formatDate(menu.ext.xCanonicalTime) : ""
94+ message: menu && menu.ext.xCanonicalText ? menu.ext.xCanonicalText : ""
95+ replyButtonText: actionsDescription && actionsDescription[0].label ? actionsDescription[0].label : "Send"
96+ // icons
97+ avatar: menu && menu.ext.icon !== undefined ? menu.ext.icon : "qrc:/indicators/artwork/messaging/default_contact.png"
98+ appIcon: menu && menu.ext.xCanonicalAppIcon !== undefined ? menu.ext.xCanonicalAppIcon : "qrc:/indicators/artwork/messaging/default_app.svg"
99+ // actions
100+ replyEnabled: replyAction.valid && replyAction.enabled
101+
102+ onActivateApp: {
103+ menuItem.model.activate(modelIndex, true);
104+ }
105+ onDismiss: {
106+ menuItem.model.activate(modelIndex, false);
107+ }
108+ onReply: {
109+ replyAction.activate(value);
110+ }
111+ }
112+ }
113+ Component {
114+ id: snapDecision
115+ SnapDecision {
116+ property var activateAction: QMenuModel.UnityMenuAction {
117+ model: menuItem.model
118+ index: modelIndex
119+ name: menu && actionsDescription[0].name ? actionsDescription[0].name : ""
120+ }
121+ property var replyAction: QMenuModel.UnityMenuAction {
122+ model: menuItem.model
123+ index: modelIndex
124+ name: menu && actionsDescription[1].name ? actionsDescription[1].name : ""
125+ }
126+
127+ // text
128+ title: menu && menu.label ? menu.label : ""
129+ time: menu ? Utils.formatDate(menu.ext.xCanonicalTime) : ""
130+ message: menu && menu.ext.xCanonicalText ? menu.ext.xCanonicalText : ""
131+ actionButtonText: actionsDescription && actionsDescription[0].label ? actionsDescription[0].label : "Call back"
132+ replyButtonText: actionsDescription && actionsDescription[1].label ? actionsDescription[1].label : "Send"
133+ replyMessages: actionsDescription && actionsDescription[1]["parameter-hint"] ? actionsDescription[1]["parameter-hint"] : ""
134+ // icons
135+ avatar: menu && menu.ext.icon !== undefined ? menu.ext.icon : "qrc:/indicators/artwork/messaging/default_contact.png"
136+ appIcon: menu && menu.ext.xCanonicalAppIcon !== undefined ? menu.ext.xCanonicalAppIcon : "qrc:/indicators/artwork/messaging/default_app.svg"
137+ // actions
138+ activateEnabled: activateAction.valid && activateAction.enabled
139+ replyEnabled: replyAction.valid && replyAction.enabled
140+
141+ onActivateApp: {
142+ menuItem.model.activate(modelIndex, true);
143+ }
144+ onDismiss: {
145+ menuItem.model.activate(modelIndex, false);
146+ }
147+ onActivate: {
148+ activateAction.activate();
149+ }
150+ onReply: {
151+ replyAction.activate(value);
152+ }
153+ }
154+ }
155+ }
156+
157+ function loadMessage(actions)
158+ {
159+ var parameterType = ""
160+ for (var actIndex in actions) {
161+ var desc = actions[actIndex];
162+ if (desc["parameter-type"] !== undefined) {
163+ parameterType += desc["parameter-type"];
164+ } else {
165+ parameterType += "_";
166+ }
167+ }
168+
169+ if (parameterType === "") {
170+ return simpleTextMessage;
171+ } else if (parameterType === "s") {
172+ return textMessage;
173+ } else if (parameterType === "_s") {
174+ return snapDecision;
175+ } else {
176+ console.debug("Unknown paramater type: " + parameterType);
177+ }
178+ return undefined;
179+ }
180+}
plugins/Unity/IndicatorsLegacy/Messaging/qml/QuickReply.qml → plugins/Unity/Indicators/Messaging/qml/QuickReply.qmlrenamed+10−5
@@ -23,12 +23,13 @@ import Ubuntu.Components 0.1
2323import Unity.IndicatorsLegacy 0.1 as Indicators
2424
2525Item {
26− property alias actionGroup: actionTextField.actionGroup
27− property alias action: actionTextField.action
28−
26+ id: quickReply
2927 property alias buttonText: actionTextField.buttonText
3028 property real expandedHeight: childrenRect.height
3129 property alias messages : messagelistRepeater.model
30+ property alias replyEnabled: actionTextField.activateEnabled
31+
32+ signal reply(var value)
3233
3334 Item {
3435 id: header
@@ -83,10 +84,9 @@ Item {
8384
8485 height: childrenRect.height
8586
86− Rectangle {
87+ Item {
8788 width: messagelist.width
8889 height: units.gu(5)
89− color: "#333230"
9090
9191 Label {
9292 id: __label
@@ -150,6 +150,11 @@ Item {
150150
151151 anchors.fill: parent
152152 anchors.margins: units.gu(1)
153+ activateEnabled: replyEnabled
154+
155+ onActivate: {
156+ quickReply.reply(value)
157+ }
153158 }
154159
155160 Indicators.HLine {
plugins/Unity/IndicatorsLegacy/Messaging/qml/SimpleTextMessage.qml → plugins/Unity/Indicators/Messaging/qml/SimpleTextMessage.qmlrenamed+7−4
@@ -20,17 +20,20 @@
2020
2121import QtQuick 2.0
2222import Ubuntu.Components 0.1
23−import "utils.js" as Utils
2423
2524HeroMessage {
2625 id: __heroMessage
2726
27+ property string title: ""
28+ property string time: ""
29+ property string message: ""
30+
2831 property alias footer: footerLoader.sourceComponent
2932
3033 expandedHeight: fullMessage.y + fullMessage.height + units.gu(2)
31− heroMessageHeader.titleText.text: menu ? menu.label : ""
32− heroMessageHeader.subtitleText.text: menu ? Utils.formatDate(menu.extra.canonical_time) : ""
33− heroMessageHeader.bodyText.text: menu ? menu.extra.canonical_text : ""
34+ heroMessageHeader.titleText.text: title
35+ heroMessageHeader.subtitleText.text: time
36+ heroMessageHeader.bodyText.text: message
3437
3538 Item {
3639 id: fullMessage
plugins/Unity/IndicatorsLegacy/Messaging/qml/SnapDecision.qml → plugins/Unity/Indicators/Messaging/qml/SnapDecision.qmlrenamed+33−14
@@ -20,19 +20,33 @@
2020
2121import QtQuick 2.0
2222import Ubuntu.Components 0.1
23−import Unity.IndicatorsLegacy 0.1 as Indicators
23+import Unity.Indicators 0.1 as Indicators
2424import "utils.js" as Utils
2525
2626HeroMessage {
2727 id: snapDecision
2828
29+ property string title: ""
30+ property string time: ""
31+ property string message: ""
32+
33+ property bool activateEnabled: true
34+ property alias actionButtonText: actionButton.text
35+
36+ property bool replyEnabled: true
37+ property alias replyMessages: quickreply.messages
38+ property alias replyButtonText: quickreply.buttonText
39+
2940 expandedHeight: buttons.y + buttons.height + quickreply.height + units.gu(2)
30− heroMessageHeader.titleText.text: menu ? menu.label : ""
31− heroMessageHeader.subtitleText.text: menu ? menu.extra.canonical_text : ""
41+ heroMessageHeader.titleText.text: title
42+ heroMessageHeader.subtitleText.text: message
3243 heroMessageHeader.subtitleText.color: "#e8e1d0"
33− heroMessageHeader.bodyText.text: menu ? Utils.formatDate(menu.extra.canonical_time) : ""
44+ heroMessageHeader.bodyText.text: time
3445 heroMessageHeader.bodyText.color: "#8f8f88"
3546
47+ signal activate
48+ signal reply(string value)
49+
3650 Item {
3751 id: buttons
3852
@@ -62,16 +76,19 @@ HeroMessage {
6276 }
6377 }
6478
65− ActionButton {
66− actionGroup: snapDecision.actionGroup
67− action: actionsDescription[0].name
68−
69− text: actionsDescription ? actionsDescription[0].label : "Call back"
70− color: "#c94212"
79+ Button {
80+ id: actionButton
81+ text: "Call back"
82+ color: enabled ? "#c94212" : "#bababa"
7183 anchors.right: parent.right
7284 anchors.top: parent.top
7385 anchors.bottom: parent.bottom
7486 width: (parent.width - units.gu(1)) / 2
87+ enabled: snapDecision.activateEnabled
88+
89+ onClicked: {
90+ snapDecision.activate();
91+ }
7592 }
7693
7794 states: State {
@@ -95,11 +112,12 @@ HeroMessage {
95112 QuickReply {
96113 id: quickreply
97114
98− actionGroup: snapDecision.actionGroup
99− action: actionsDescription[1].name
115+ onReply: {
116+ snapDecision.reply(value);
117+ }
100118
101− messages: actionsDescription ? actionsDescription[1]["parameter-hint"] : ""
102− buttonText: actionsDescription ? actionsDescription[1].label : "send"
119+ messages: ""
120+ buttonText: "Send"
103121 anchors {
104122 top: buttons.bottom
105123 topMargin: units.gu(2)
@@ -109,6 +127,7 @@ HeroMessage {
109127 height: 0
110128 opacity: 0.0
111129 enabled: false
130+ replyEnabled: snapDecision.replyEnabled
112131
113132 states: State {
114133 name: "expanded"
plugins/Unity/IndicatorsLegacy/Messaging/qml/TextMessage.qml → plugins/Unity/Indicators/Messaging/qml/TextMessage.qmlrenamed+12−4
@@ -20,16 +20,24 @@
2020
2121import QtQuick 2.0
2222import Ubuntu.Components 0.1
23−import Unity.IndicatorsLegacy 0.1 as Indicators
23+import Unity.Indicators 0.1 as Indicators
2424
2525SimpleTextMessage {
2626 id: simpleMessage
2727
28+ property bool replyEnabled: false
29+ property string replyButtonText: "Send"
30+
31+ signal reply(string value)
32+
2833 footer: ActionTextField {
2934 anchors.fill: parent
30− actionGroup: simpleMessage.actionGroup
31− action: actionsDescription[0].name
3235
33− buttonText: actionsDescription ? actionsDescription[0].label : "Send"
36+ activateEnabled: simpleMessage.replyEnabled
37+ buttonText: simpleMessage.replyButtonText
38+
39+ onActivate: {
40+ simpleMessage.reply(value);
41+ }
3442 }
3543}
plugins/Unity/IndicatorsLegacy/Messaging/qml/qmldir → plugins/Unity/Indicators/Messaging/qml/qmldirrenamed+2−2
@@ -1,11 +1,11 @@
1−module Unity.IndicatorsLegacy.Messaging
1+module Unity.Indicators.Messaging
22
33ActionButton 0.1 ActionButton.qml
44ActionTextField 0.1 ActionTextField.qml
55GroupedMessage 0.1 GroupedMessage.qml
66HeroMessage 0.1 HeroMessage.qml
77HeroMessageHeader 0.1 HeroMessageHeader.qml
8−MessageMenuItem 0.1 MessageMenuItem.qml
8+MessageMenuItemFactory 0.1 MessageMenuItemFactory.qml
99QuickReply 0.1 QuickReply.qml
1010SimpleTextMessage 0.1 SimpleTextMessage.qml
1111SnapDecision 0.1 SnapDecision.qml
plugins/Unity/IndicatorsLegacy/Messaging/qml/utils.js → plugins/Unity/Indicators/Messaging/qml/utils.jsrenamed

The content is the same.

plugins/Unity/Indicators/plugin.cpp+2
@@ -42,6 +42,8 @@ static QObject* menuModelCacheSingleton(QQmlEngine* engine, QJSEngine* scriptEng
4242
4343void Indicators2Plugin::registerTypes(const char *uri)
4444{
45+ Q_INIT_RESOURCE(indicators);
46+
4547 qmlRegisterType<IndicatorsManager>(uri, 0, 1, "IndicatorsManager");
4648 qmlRegisterType<IndicatorsModel>(uri, 0, 1, "IndicatorsModel");
4749 qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
plugins/Unity/Indicators/qml/BaseMenuItem.qml+1−1
@@ -24,7 +24,7 @@ import Ubuntu.Components.ListItems 0.1 as ListItem
2424ListItem.Standard {
2525 id: baseMenu
2626
27− property bool menuActivated: false
27+ property bool menuSelected: false
2828
2929 signal selectMenu()
3030 signal deselectMenu()
plugins/Unity/Indicators/qml/IndicatorPage.qml+33−6
@@ -61,7 +61,34 @@ IndicatorBase {
6161 // Only allow flicking if the content doesn't fit on the page
6262 interactive: contentHeight > height
6363
64− currentIndex: -1
64+ property int selectedIndex: -1
65+ property bool blockCurrentIndexChange: false
66+ // for count = 0
67+ onCountChanged: {
68+ if (count == 0 && selectedIndex != -1) {
69+ selectedIndex = -1;
70+ }
71+ }
72+ // for highlight following
73+ onSelectedIndexChanged: {
74+ if (currentIndex != selectedIndex) {
75+ var blocked = blockCurrentIndexChange;
76+ blockCurrentIndexChange = true;
77+
78+ currentIndex = selectedIndex;
79+
80+ blockCurrentIndexChange = blocked;
81+ }
82+ }
83+ // for item addition/removal
84+ onCurrentIndexChanged: {
85+ if (!blockCurrentIndexChange) {
86+ if (selectedIndex != -1 && selectedIndex != currentIndex) {
87+ selectedIndex = currentIndex;
88+ }
89+ }
90+ }
91+
6592 delegate: Item {
6693 id: menuDelegate
6794
@@ -90,10 +117,10 @@ IndicatorBase {
90117 menuStack.push(mainMenu.model.submenu(index));
91118 }
92119
93− if (item.hasOwnProperty("menuActivated")) {
94− item.menuActivated = Qt.binding(function() { return ListView.isCurrentItem; });
95− item.selectMenu.connect(function() { ListView.view.currentIndex = index });
96− item.deselectMenu.connect(function() { ListView.view.currentIndex = -1 });
120+ if (item.hasOwnProperty("menuSelected")) {
121+ item.menuSelected = Qt.binding(function() { return mainMenu.selectedIndex == index; });
122+ item.selectMenu.connect(function() { mainMenu.selectedIndex = index; });
123+ item.deselectMenu.connect(function() { mainMenu.selectedIndex = -1; });
97124 }
98125 if (item.hasOwnProperty("menu")) {
99126 item.menu = Qt.binding(function() { return model; });
@@ -150,7 +177,7 @@ IndicatorBase {
150177
151178 function reset()
152179 {
153− mainMenu.currentIndex = -1;
180+ mainMenu.selectedIndex = -1;
154181 mainMenu.positionViewAtBeginning();
155182 }
156183}
plugins/Unity/Indicators/qml/MenuItemFactory.qml+62−12
@@ -20,6 +20,7 @@
2020import QtQuick 2.0
2121import Unity.Indicators 0.1 as Indicators
2222import Unity.Indicators.Network 0.1 as ICNetwork
23+import Unity.Indicators.Messaging 0.1 as ICMessaging
2324import QMenuModel 0.1 as QMenuModel
2425
2526Item {
@@ -38,6 +39,9 @@ Item {
3839 "com.canonical.indicator.slider" : sliderMenu,
3940 "com.canonical.indicator.switch" : switchMenu,
4041
42+ "com.canonical.indicator.messages.messageitem" : messageItem,
43+ "com.canonical.indicator.messages.sourceitem" : groupedMessage,
44+
4145 "com.canonical.unity.slider" : sliderMenu,
4246 "com.canonical.unity.switch" : switchMenu,
4347
@@ -45,15 +49,17 @@ Item {
4549 "unity.widgets.systemsettings.tablet.accesspoint" : accessPoint,
4650 }
4751
52+ Component { id: divMenu; Indicators.DivMenuItem {} }
53+
4854 Component {
4955 id: sliderMenu;
5056 Indicators.SliderMenuItem {
5157 property QtObject menu: null
5258
5359 text: menu && menu.label ? menu.label : ""
54− icon: menu ? menu.icon : ""
55− minIcon: menu.ext.minIcon
56− maxIcon: menu.ext.maxIcon
60+ icon: menu && menu.icon ? menu.icon : ""
61+ minIcon: menu && menu.ext.minIcon ? menu.ext.minIcon : ""
62+ maxIcon: menu && menu.ext.maxIcon ? menu.ext.maxIcon : ""
5763
5864 minimumValue: menu.ext.minValue ? menu.ext.minValue : 0.0
5965 maximumValue: {
@@ -79,8 +85,6 @@ Item {
7985 }
8086 }
8187
82− Component { id: divMenu; Indicators.DivMenuItem {} }
83−
8488 Component {
8589 id: buttonMenu;
8690 Indicators.ButtonMenuItem {
@@ -89,7 +93,9 @@ Item {
8993 text: menu && menu.label ? menu.label : ""
9094 enabled: menu ? menu.sensitive : false
9195
92− onActivate: model.activate(modelIndex);
96+ onActivate: {
97+ model.activate(modelIndex);
98+ }
9399 }
94100 }
95101 Component {
@@ -118,12 +124,14 @@ Item {
118124 property QtObject menu: null
119125
120126 text: menu && menu.label ? menu.label : ""
121− icon: menu ? menu.icon : ""
127+ icon: menu && menu.icon ? menu.icon : ""
122128 checkable: menu ? (menu.isCheck || menu.isRadio) : false
123129 checked: checkable ? menu.isToggled : false
124130 enabled: menu ? menu.sensitive : false
125131
126− onActivate: model.activate(modelIndex);
132+ onActivate: {
133+ model.activate(modelIndex);
134+ }
127135 }
128136 }
129137
@@ -133,11 +141,13 @@ Item {
133141 property QtObject menu: null
134142
135143 text: menu && menu.label ? menu.label : ""
136− icon: menu ? menu.icon : ""
144+ icon: menu && menu.icon ? menu.icon : ""
137145 checked: menu ? menu.isToggled : false
138146 enabled: menu ? menu.sensitive : false
139147
140− onActivate: model.activate(modelIndex);
148+ onActivate: {
149+ model.activate(modelIndex);
150+ }
141151 }
142152 }
143153
@@ -161,11 +171,11 @@ Item {
161171 property QtObject menu: null
162172 property var strengthAction: QMenuModel.UnityMenuAction {
163173 model: menuFactory.model ? menuFactory.model : null
174+ index: modelIndex
164175 name: menu ? menu.ext.xCanonicalWifiApStrengthAction : ""
165176 }
166177
167178 text: menu && menu.label ? menu.label : ""
168− icon: menu ? menu.icon : ""
169179 secure: menu ? menu.ext.xCanonicalWifiApIsSecure : false
170180 adHoc: menu ? menu.ext.xCanonicalWifiApIsAdhoc : false
171181 checked: menu ? menu.isToggled : false
@@ -177,7 +187,47 @@ Item {
177187 'x-canonical-wifi-ap-is-secure': 'bool',
178188 'x-canonical-wifi-ap-strength-action': 'string'});
179189 }
180− onActivate: model.activate(modelIndex);
190+ onActivate: {
191+ model.activate(modelIndex);
192+ }
193+ }
194+ }
195+
196+ Component {
197+ id: messageItem
198+ ICMessaging.MessageMenuItemFactory {
199+
200+ property QtObject menu: null
201+ model: menuFactory.model ? menuFactory.model : null
202+
203+ Component.onCompleted: {
204+ model.loadExtendedAttributes(modelIndex, {'x-canonical-time': 'int64',
205+ 'x-canonical-text': 'string',
206+ 'x-canonical-message-actions': 'variant',
207+ 'icon': 'icon',
208+ 'x-canonical-app-icon': 'icon'});
209+ }
210+ }
211+ }
212+
213+ Component {
214+ id: groupedMessage
215+ ICMessaging.GroupedMessage {
216+ property QtObject menu: null
217+
218+ title: menu && menu.label ? menu.label : ""
219+ count: menu && menu.actionState[0] ? menu.actionState[0] : "0"
220+ appIcon: menu && menu.ext.icon !== undefined ? menu.ext.icon : "qrc:/indicators/artwork/messaging/default_app.svg"
221+
222+ Component.onCompleted: {
223+ model.loadExtendedAttributes(modelIndex, {'icon': 'icon'});
224+ }
225+ onActivateApp: {
226+ model.activate(modelIndex, true);
227+ }
228+ onDismiss: {
229+ model.activate(modelIndex, false);
230+ }
181231 }
182232 }
183233
plugins/Unity/IndicatorsLegacy/resources/artwork/messaging/default_app.svg → plugins/Unity/Indicators/resources/artwork/messaging/default_app.svgrenamed

The content is the same.

plugins/Unity/IndicatorsLegacy/resources/artwork/messaging/default_contact.png → plugins/Unity/Indicators/resources/artwork/messaging/default_contact.pngrenamed

Binary file not shown.

plugins/Unity/IndicatorsLegacy/resources/artwork/messaging/message_sms01_54px.png → plugins/Unity/Indicators/resources/artwork/messaging/message_sms01_54px.pngrenamed

Binary file not shown.

plugins/Unity/Indicators/resources/indicators.qrc+3
@@ -1,5 +1,8 @@
11<RCC>
22 <qresource prefix="/indicators">
33 <file>artwork/network/secure.svg</file>
4+ <file>artwork/messaging/default_contact.png</file>
5+ <file>artwork/messaging/default_app.svg</file>
6+ <file>artwork/messaging/message_sms01_54px.png</file>
47 </qresource>
58</RCC>
plugins/Unity/IndicatorsLegacy/CMakeLists.txt−1
@@ -8,7 +8,6 @@ find_package(Qt5Core REQUIRED)
88find_package(Qt5Quick REQUIRED)
99
1010add_subdirectory(qml)
11−add_subdirectory(Messaging)
1211add_subdirectory(Network)
1312
1413include_directories(
plugins/Unity/IndicatorsLegacy/Messaging/qml/CMakeLists.txtdeleted−5
@@ -1,5 +0,0 @@
1−# export_qmlfiles macro
2−include(Plugins)
3−
4−# export the qmldir, *.qml files.
5−export_qmlfiles(Unity.IndicatorsLegacy.Messaging Unity/IndicatorsLegacy/Messaging)
plugins/Unity/IndicatorsLegacy/Messaging/qml/MessageMenuItem.qmldeleted−96
@@ -1,96 +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 Lesser General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU Lesser General Public License for more details.
12− *
13− * You should have received a copy of the GNU Lesser General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− *
16− * Authors:
17− * Renato Araujo Oliveira Filho <renato@canonical.com>
18− * Olivier Tilloy <olivier.tilloy@canonical.com>
19− */
20−
21−import QtQuick 2.0
22−import Ubuntu.Components 0.1
23−import Unity.IndicatorsLegacy 0.1 as Indicators
24−
25−Indicators.BasicMenuItem {
26− property variant actionsDescription: menu ? menu.extra.canonical_message_actions : undefined
27−
28− onActionGroupChanged: loadItem()
29− onActionsDescriptionChanged: loadItem()
30− implicitHeight: contents.status == Loader.Ready ? contents.item.implicitHeight : 0
31−
32− Loader {
33− id: contents
34−
35− anchors.fill: parent
36− // Binding all properties for the item, to make sure that any change in the
37− // property will be propagated to the contents.item at any time
38− Binding {
39− target: contents.item
40− property: "menuActivated"
41− value: menuActivated
42− when: (contents.status == Loader.Ready)
43− }
44−
45− Binding {
46− target: contents.item
47− property: "actionGroup"
48− value: actionGroup
49− when: (contents.status == Loader.Ready)
50− }
51−
52− Binding {
53− target: contents.item
54− property: "menu"
55− value: menu
56− when: (contents.status == Loader.Ready)
57− }
58−
59− Binding {
60− target: contents.item
61− property: "actionsDescription"
62− value: actionsDescription
63− when: (contents.status == Loader.Ready)
64− }
65−
66− Connections {
67− target: contents.item ? contents.item : null
68− onActivateMenu: activateMenu()
69− onDeactivateMenu: deactivateMenu()
70− }
71− }
72−
73−
74− function loadItem()
75− {
76− var parameterType = ""
77− for (var actIndex in actionsDescription) {
78− var desc = actionsDescription[actIndex];
79− if (desc["parameter-type"] !== undefined) {
80− parameterType += desc["parameter-type"];
81− } else {
82− parameterType += "_";
83− }
84− }
85−
86− if (parameterType === "") {
87− contents.source = "SimpleTextMessage.qml";
88− } else if (parameterType === "s") {
89− contents.source = "TextMessage.qml";
90− } else if (parameterType === "_s") {
91− contents.source = "SnapDecision.qml";
92− } else {
93− console.debug("Unknown paramater type: " + parameterType);
94− }
95− }
96−}
plugins/Unity/IndicatorsLegacy/qml/MenuItemFactory.qml−8
@@ -19,7 +19,6 @@
1919
2020import QtQuick 2.0
2121import Unity.IndicatorsLegacy 0.1 as Indicators
22−import Unity.IndicatorsLegacy.Messaging 0.1 as ICMessaging
2322import Unity.IndicatorsLegacy.Network 0.1 as ICNetwork
2423
2524Item {
@@ -47,10 +46,6 @@ Item {
4746 "com.canonical.indicator.slider" : sliderMenu,
4847 "com.canonical.indicator.switch" : switchMenu,
4948
50− "com.canonical.indicator.messages.messageitem" : messageItem,
51− "com.canonical.indicator.messages.snapdecision" : snapDecision,
52− "com.canonical.indicator.messages.sourceitem" : groupedMessage,
53−
5449 "unity.widget.systemsettings.tablet.sectiontitle" : wifiSection,
5550 "unity.widgets.systemsettings.tablet.wifisection" : wifiSection,
5651 "unity.widgets.systemsettings.tablet.accesspoint" : accessPoint,
@@ -62,9 +57,6 @@ Item {
6257 Component { id: divMenu; Indicators.DivMenuItem {} }
6358 Component { id: sectionMenu; Indicators.SectionMenuItem {} }
6459 Component { id: progressMenu; Indicators.ProgressMenuItem {} }
65− Component { id: messageItem; ICMessaging.MessageMenuItem {} }
66− Component { id: snapDecision; ICMessaging.SnapDecision {} }
67− Component { id: groupedMessage; ICMessaging.GroupedMessage {} }
6860 Component { id: wifiSection; ICNetwork.WifiSection {} }
6961 Component { id: accessPoint; ICNetwork.AccessPoint {} }
7062 Component { id: indicatorMenu; Indicators.MenuItem {} }
plugins/Unity/IndicatorsLegacy/resources/indicators.qrc−3
@@ -1,7 +1,4 @@
11<RCC>
22 <qresource prefix="/indicators">
3− <file>artwork/messaging/default_contact.png</file>
4− <file>artwork/messaging/default_app.svg</file>
5− <file>artwork/messaging/message_sms01_54px.png</file>
63 </qresource>
74</RCC>
plugins/Unity/Launcher/launchermodel.cpp+12−3
@@ -115,9 +115,11 @@ void LauncherModel::move(int oldIndex, int newIndex)
115115 m_list.move(oldIndex, newIndex);
116116 endMoveRows();
117117
118− storeAppList();
119−
120− pin(m_list.at(newIndex)->appId());
118+ if (!m_list.at(newIndex)->pinned()) {
119+ pin(m_list.at(newIndex)->appId());
120+ } else {
121+ storeAppList();
122+ }
121123}
122124
123125void LauncherModel::pin(const QString &appId, int index)
@@ -146,6 +148,8 @@ void LauncherModel::pin(const QString &appId, int index)
146148 m_list.insert(index, item);
147149 endInsertRows();
148150 }
151+
152+ storeAppList();
149153}
150154
151155void LauncherModel::requestRemove(const QString &appId)
@@ -155,6 +159,11 @@ void LauncherModel::requestRemove(const QString &appId)
155159 return;
156160 }
157161
162+ if (m_appManager->findApplication(appId)) {
163+ m_list.at(index)->setPinned(false);
164+ return;
165+ }
166+
158167 beginRemoveRows(QModelIndex(), index, index);
159168 m_list.takeAt(index)->deleteLater();
160169 endRemoveRows();
plugins/Unity/categories.cpp+12−1
@@ -21,6 +21,7 @@
2121// self
2222#include "categories.h"
2323#include "categoryresults.h"
24+#include <QDebug>
2425
2526// TODO: use something from libunity once it's public
2627enum CategoryColumn {
@@ -62,7 +63,17 @@ Categories::getResults(int index) const
6263
6364 unsigned categoryIndex = static_cast<unsigned>(index);
6465 auto unity_results = m_unityScope->GetResultsForCategory(categoryIndex);
65− results->setModel(unity_results->model());
66+ if (unity_results) {
67+ results->setModel(unity_results->model());
68+ } else {
69+ // No results model returned by unity core; this can be the case when the global
70+ // results model of this scope is still not set in unity core. Don't set backend
71+ // model in DeeListModel - it will still beahve properly as an empty model. Since
72+ // we're connected to the category model change signal, and it is set by unity core
73+ // at the same time as results model (on channel opening), we'll reset category
74+ // results models with proper models when we're notifed again.
75+ qWarning() << "No results model for category" << categoryIndex;
76+ }
6677
6778 m_results.insert(index, results);
6879 }
plugins/Unity/iconutils.cpp+1−1
@@ -30,7 +30,7 @@ QString gIconToDeclarativeImageProviderString(QString const &giconString)
3030 if (giconString.isEmpty()) return giconString;
3131
3232 if (giconString.startsWith('/') || giconString.startsWith(QLatin1String("http")) ||
33− giconString.startsWith(QLatin1String("file:"))) {
33+ giconString.startsWith(QLatin1String("file:")) || giconString.startsWith(QLatin1String("image:"))) {
3434 return giconString;
3535 }
3636
plugins/Unity/plugin.cpp+2
@@ -35,6 +35,7 @@
3535#include "categoryresults.h"
3636#include "bottombarvisibilitycommunicatorshell.h"
3737#include "genericoptionsmodel.h"
38+#include "result.h"
3839
3940// libqtdee
4041#include "deelistmodel.h"
@@ -50,6 +51,7 @@ void UnityPlugin::registerTypes(const char *uri)
5051 qmlRegisterUncreatableType<PreviewInfoHint>(uri, 0, 1, "PreviewInfoHint", "Can't create PreviewInfoHint object in QML.");
5152 qmlRegisterUncreatableType<SocialPreviewComment>(uri, 0, 1, "SocialPreviewComment", "Can't create SocialPreviewComment object in QML.");
5253 qmlRegisterUncreatableType<GenericOptionsModel>(uri, 0, 1, "GenericOptionsModel", "Can't create options model in QML.");
54+ qmlRegisterUncreatableType<Result>(uri, 0, 1, "Result", "Can't create result object in QML.");
5355 qmlRegisterType<Scope>(uri, 0, 1, "Scope");
5456 qmlRegisterType<Scopes>(uri, 0, 1, "Scopes");
5557 qmlRegisterType<Categories>(uri, 0, 1, "Categories");
plugins/Unity/preview.cpp+17−2
@@ -39,9 +39,12 @@
3939#include <UnityCore/MusicPreview.h>
4040#include <UnityCore/SocialPreview.h>
4141
42+#include <UnityCore/GLibWrapper.h>
43+
4244Preview::Preview(QObject *parent):
4345 QObject(parent),
44− m_unityPreview(nullptr)
46+ m_unityPreview(nullptr),
47+ m_result(new Result(this))
4548{
4649}
4750
@@ -123,6 +126,11 @@ QString Preview::imageSourceUri() const
123126 return QString::null;
124127}
125128
129+QVariant Preview::result() const
130+{
131+ return QVariant::fromValue(m_result);
132+}
133+
126134Preview* Preview::newFromUnityPreview(unity::dash::Preview::Ptr unityPreview)
127135{
128136 Preview* preview = nullptr;
@@ -151,6 +159,7 @@ Preview* Preview::newFromUnityPreview(unity::dash::Preview::Ptr unityPreview)
151159void Preview::setUnityPreviewBase(unity::dash::Preview::Ptr unityPreview)
152160{
153161 m_unityPreview = unityPreview;
162+ m_result->setPreview(unityPreview);
154163
155164 qDeleteAll(m_infoHints);
156165 m_infoHints.clear();
@@ -181,8 +190,14 @@ void Preview::execute(const QString& actionId, const QHash<QString, QVariant>& h
181190{
182191 if (m_unityPreview) {
183192 auto unityHints = convertToHintsMap(hints);
184− m_unityPreview->PerformAction(actionId.toStdString(), unityHints);
193+ m_actionCancellable.Renew();
194+ m_unityPreview->PerformAction(actionId.toStdString(), unityHints, nullptr, m_actionCancellable);
185195 } else {
186196 qWarning() << "Preview not set";
187197 }
188198}
199+
200+void Preview::cancelAction()
201+{
202+ m_actionCancellable.Cancel();
203+}
plugins/Unity/preview.h+7
@@ -31,7 +31,9 @@
3131#include <UnityCore/Preview.h>
3232
3333// local
34+#include "result.h"
3435#include "previewaction.h"
36+#include <UnityCore/GLibWrapper.h>
3537
3638class Q_DECL_EXPORT Preview : public QObject
3739{
@@ -46,6 +48,7 @@ class Q_DECL_EXPORT Preview : public QObject
4648 Q_PROPERTY(QVariantMap infoMap READ infoHintsHash NOTIFY previewChanged)
4749 Q_PROPERTY(QString image READ image NOTIFY previewChanged)
4850 Q_PROPERTY(QString imageSourceUri READ imageSourceUri NOTIFY previewChanged)
51+ Q_PROPERTY(QVariant result READ result NOTIFY previewChanged)
4952
5053public:
5154 explicit Preview(QObject *parent = 0);
@@ -60,8 +63,10 @@ public:
6063 QVariantMap infoHintsHash() const;
6164 QString image() const;
6265 QString imageSourceUri() const;
66+ QVariant result() const;
6367
6468 Q_INVOKABLE void execute(const QString& actionId, const QHash<QString, QVariant>& hints);
69+ Q_INVOKABLE void cancelAction();
6570
6671Q_SIGNALS:
6772 void previewChanged();
@@ -70,6 +75,7 @@ protected:
7075 virtual void setUnityPreview(unity::dash::Preview::Ptr unityPreview);
7176
7277 unity::dash::Preview::Ptr m_unityPreview;
78+ Result* m_result;
7379
7480private:
7581 void setUnityPreviewBase(unity::dash::Preview::Ptr unityPreview);
@@ -77,6 +83,7 @@ private:
7783 QList<QObject *> m_actions;
7884 QList<QObject *> m_infoHints;
7985 QVariantMap m_infoHintsHash;
86+ unity::glib::Cancellable m_actionCancellable;
8087};
8188
8289Q_DECLARE_METATYPE(Preview *)
plugins/Unity/result.cppnew file+82
@@ -0,0 +1,82 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#include "result.h"
21+#include "variantutils.h"
22+
23+Result::Result(QObject *parent) :
24+ QObject(parent)
25+{
26+}
27+
28+Result::Result(unity::dash::Preview::Ptr preview, QObject *parent) :
29+ QObject(parent),
30+ m_preview(preview)
31+{
32+}
33+
34+void Result::setPreview(unity::dash::Preview::Ptr preview)
35+{
36+ m_preview = preview;
37+}
38+
39+QString Result::uri() const
40+{
41+ return m_preview != nullptr ? QString::fromStdString(m_preview->preview_result.uri) : QString::null;
42+}
43+
44+QString Result::iconHint() const
45+{
46+ return m_preview != nullptr ? QString::fromStdString(m_preview->preview_result.icon_hint) : QString::null;
47+}
48+
49+unsigned Result::categoryIndex() const
50+{
51+ return m_preview != nullptr ? m_preview->preview_result.category_index : 0;
52+}
53+
54+unsigned Result::resultType() const
55+{
56+ return m_preview != nullptr ? m_preview->preview_result.result_type : 0;
57+}
58+
59+QString Result::mimeType() const
60+{
61+ return m_preview != nullptr ? QString::fromStdString(m_preview->preview_result.mimetype) : QString::null;
62+}
63+
64+QString Result::title() const
65+{
66+ return m_preview != nullptr ? QString::fromStdString(m_preview->preview_result.name) : QString::null;
67+}
68+
69+QString Result::comment() const
70+{
71+ return m_preview != nullptr ? QString::fromStdString(m_preview->preview_result.comment) : QString::null;
72+}
73+
74+QString Result::dndUri() const
75+{
76+ return m_preview != nullptr ? QString::fromStdString(m_preview->preview_result.dnd_uri) : QString::null;
77+}
78+
79+QVariant Result::metadata() const
80+{
81+ return m_preview != nullptr ? convertToQVariantHash(m_preview->preview_result.hints) : QVariant();
82+}
plugins/Unity/result.hnew file+69
@@ -0,0 +1,69 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#ifndef RESULT_H
21+#define RESULT_H
22+
23+// Qt
24+#include <QObject>
25+#include <QVariant>
26+
27+// libunity-core
28+#include <UnityCore/Preview.h>
29+
30+class Q_DECL_EXPORT Result : public QObject
31+{
32+ Q_OBJECT
33+
34+ Q_PROPERTY(QString uri READ uri CONSTANT)
35+ Q_PROPERTY(QString iconHint READ iconHint CONSTANT)
36+ Q_PROPERTY(unsigned categoryIndex READ categoryIndex CONSTANT)
37+ Q_PROPERTY(unsigned resultType READ resultType CONSTANT)
38+ Q_PROPERTY(QString mimeType READ mimeType CONSTANT)
39+ Q_PROPERTY(QString title READ title CONSTANT)
40+ Q_PROPERTY(QString comment READ comment CONSTANT)
41+ Q_PROPERTY(QString dndUri READ dndUri CONSTANT)
42+ Q_PROPERTY(QVariant metadata READ metadata CONSTANT)
43+
44+public:
45+ Result(QObject *parent = nullptr);
46+ Result(unity::dash::Preview::Ptr preview, QObject *parent = nullptr);
47+
48+ void setPreview(unity::dash::Preview::Ptr preview);
49+
50+ QString uri() const;
51+ QString iconHint() const;
52+ unsigned categoryIndex() const;
53+ unsigned resultType() const;
54+ QString mimeType() const;
55+ QString title() const;
56+ QString comment() const;
57+ QString dndUri() const;
58+ QVariant metadata() const;
59+
60+private:
61+ /* Keep reference to the original preview to access result attributes via it, rather than keeping copies of them;
62+ this will save us a bit on copying, especially as UI is mostly interested in just uri.
63+ */
64+ unity::dash::Preview::Ptr m_preview;
65+};
66+
67+Q_DECLARE_METATYPE(Result *)
68+
69+#endif
plugins/Unity/scope.cpp+20−1
@@ -175,7 +175,19 @@ void Scope::preview(const QVariant &uri, const QVariant &icon_hint, const QVaria
175175 const QVariant &comment, const QVariant &dnd_uri, const QVariant &metadata)
176176{
177177 auto res = createLocalResult(uri, icon_hint, category, result_type, mimetype, title, comment, dnd_uri, metadata);
178− m_unityScope->Preview(res);
178+ m_previewCancellable.Renew();
179+
180+ // canned queries don't have previews, must be activated
181+ if (uri.toString().startsWith("x-unity-no-preview-scopes-query://")) {
182+ m_unityScope->Activate(res);
183+ } else {
184+ m_unityScope->Preview(res, nullptr, m_previewCancellable);
185+ }
186+}
187+
188+void Scope::cancelActivation()
189+{
190+ m_previewCancellable.Cancel();
179191}
180192
181193void Scope::onActivated(unity::dash::LocalResult const& result, unity::dash::ScopeHandledType type, unity::glib::HintsMap const& hints)
@@ -199,6 +211,13 @@ void Scope::onActivated(unity::dash::LocalResult const& result, unity::dash::Sco
199211 qWarning() << "Missing goto-uri hint for GOTO_DASH_URI activation reply";
200212 }
201213 break;
214+ case unity::dash::PERFORM_SEARCH:
215+ if (hints.find("query") != hints.end()) {
216+ // note: this will emit searchQueryChanged, and shell will call setSearchQuery back with a new query,
217+ // but it will get ignored.
218+ setSearchQuery(QString::fromStdString(g_variant_get_string(hints.at("query"), nullptr)));
219+ }
220+ break;
202221 default:
203222 qWarning() << "Unhandled activation response:" << type;
204223 }
plugins/Unity/scope.h+3
@@ -82,6 +82,8 @@ public:
8282 Q_INVOKABLE void preview(const QVariant &uri, const QVariant &icon_hint, const QVariant &category,
8383 const QVariant &result_type, const QVariant &mimetype, const QVariant &title,
8484 const QVariant &comment, const QVariant &dnd_uri, const QVariant &metadata);
85+ Q_INVOKABLE void cancelActivation();
86+
8587 void setUnityScope(const unity::dash::Scope::Ptr& scope);
8688 unity::dash::Scope::Ptr unityScope() const;
8789
@@ -131,6 +133,7 @@ private:
131133 QString m_searchQuery;
132134 QString m_noResultsHint;
133135 QString m_formFactor;
136+ unity::glib::Cancellable m_previewCancellable;
134137};
135138
136139Q_DECLARE_METATYPE(Scope*)
plugins/Unity/variantutils.cpp+9
@@ -40,3 +40,12 @@ unity::glib::HintsMap convertToHintsMap(const QVariant &var)
4040 }
4141 return unity::glib::HintsMap();
4242}
43+
44+QVariantHash convertToQVariantHash(const unity::glib::HintsMap& var)
45+{
46+ QVariantHash hash;
47+ for (auto hint: var) {
48+ hash.insert(QString::fromStdString(hint.first), DeeListModel::VariantForData(hint.second));
49+ }
50+ return hash;
51+}
plugins/Unity/variantutils.h+1
@@ -28,5 +28,6 @@
2828
2929unity::glib::HintsMap convertToHintsMap(const QHash<QString, QVariant> &val);
3030unity::glib::HintsMap convertToHintsMap(const QVariant &var);
31+QVariantHash convertToQVariantHash(const unity::glib::HintsMap& var);
3132
3233#endif
po/ca.po+23−17
@@ -8,15 +8,15 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-08-27 13:36-0400\n"
11−"PO-Revision-Date: 2013-09-11 10:30+0000\n"
11+"PO-Revision-Date: 2013-09-28 07:38+0000\n"
1212"Last-Translator: David Planella <david.planella@ubuntu.com>\n"
1313"Language-Team: Catalan <ca@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-09-12 08:06+0000\n"
19−"X-Generator: Launchpad (build 16761)\n"
18+"X-Launchpad-Export-Date: 2013-09-29 06:18+0000\n"
19+"X-Generator: Launchpad (build 16774)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -88,7 +88,7 @@ msgstr "YouTube"
8888
8989#: Components/EdgeDemoOverlay.qml:145
9090msgid "Skip intro"
91−msgstr ""
91+msgstr "Omet la introducció"
9292
9393#: Components/EdgeDemo.qml:98
9494msgid "Right edge"
@@ -97,6 +97,7 @@ msgstr "Vora dreta"
9797#: Components/EdgeDemo.qml:99
9898msgid "Try swiping from the right edge to unlock the phone"
9999msgstr ""
100+"Proveu de lliscar el dit des de la vora dreta per desblocar el telèfon"
100101
101102#: Components/EdgeDemo.qml:135
102103msgid "Top edge"
@@ -105,14 +106,17 @@ msgstr "Vora superior"
105106#: Components/EdgeDemo.qml:136
106107msgid "Try swiping from the top edge to access the indicators"
107108msgstr ""
109+"Proveu de lliscar el dit des de la vora superior per accedir als indicadors"
108110
109111#: Components/EdgeDemo.qml:161
110112msgid "Close"
111−msgstr ""
113+msgstr "Tanca"
112114
113115#: Components/EdgeDemo.qml:162
114116msgid "Swipe up again to close the settings screen"
115117msgstr ""
118+"Llisqueu el dit cap amunt una altra vegada per tancar la pantalla de "
119+"configuració"
116120
117121#: Components/EdgeDemo.qml:189
118122msgid "Left edge"
@@ -121,6 +125,8 @@ msgstr "Vora esquerra"
121125#: Components/EdgeDemo.qml:190
122126msgid "Swipe from the left to reveal the launcher for quick access to apps"
123127msgstr ""
128+"Llisqueu el dit des de la vora esquerra per mostrar el llançador i accedir "
129+"ràpidament a les aplicacions"
124130
125131#: Components/EdgeDemo.qml:217
126132msgid "Well done"
@@ -145,8 +151,8 @@ msgstr "(%1)"
145151#, qt-format
146152msgid "%1 review"
147153msgid_plural "%1 reviews"
148−msgstr[0] ""
149−msgstr[1] ""
154+msgstr[0] "%1 ressenya"
155+msgstr[1] "%1 ressenyes"
150156
151157#: Dash/Apps/AppPreview.qml:175
152158msgid "Rate this"
@@ -154,7 +160,7 @@ msgstr ""
154160
155161#: Dash/Apps/AppReviews.qml:72
156162msgid "Add a review"
157−msgstr ""
163+msgstr "Afegiu una ressenya"
158164
159165#: Dash/Apps/AppReviews.qml:84
160166msgid "Review"
@@ -162,7 +168,7 @@ msgstr "Ressenya"
162168
163169#: Dash/Apps/AppReviews.qml:118
164170msgid "Send"
165−msgstr ""
171+msgstr "Envia"
166172
167173#: Dash/Apps/AppReviews.qml:136
168174msgid "Comments:"
@@ -178,11 +184,11 @@ msgstr "Recents"
178184
179185#: Dash/DashMusic.qml:29 Dash/DashVideos.qml:30
180186msgid "New Releases"
181−msgstr ""
187+msgstr "Novetats"
182188
183189#: Dash/DashMusic.qml:30
184190msgid "Top Charting"
185−msgstr ""
191+msgstr "El millor de les llistes"
186192
187193#: Dash/DashMusic.qml:91
188194msgid "Music"
@@ -190,7 +196,7 @@ msgstr "Música"
190196
191197#: Dash/DashVideos.qml:31
192198msgid "Popular Online"
193−msgstr ""
199+msgstr "Popular a la xarxa"
194200
195201#: Dash/DashVideos.qml:146
196202msgid "Videos"
@@ -198,11 +204,11 @@ msgstr "Vídeos"
198204
199205#: Dash/Video/VideoPreview.qml:130
200206msgid "Directed by:"
201−msgstr ""
207+msgstr "Dirigit per:"
202208
203209#: Dash/Video/VideoPreview.qml:153
204210msgid "Starring:"
205−msgstr ""
211+msgstr "Protagonistes:"
206212
207213#: Dash/Video/VideoPreview.qml:176
208214msgid "Author:"
@@ -210,12 +216,12 @@ msgstr "Autor:"
210216
211217#: Greeter/Lockscreen.qml:134
212218msgid "Emergency Call"
213−msgstr ""
219+msgstr "Trucada d'emergència"
214220
215221#: Greeter/PassphraseLockscreen.qml:59
216222#, qt-format
217223msgid "Hello %1"
218−msgstr ""
224+msgstr "Hola %1"
219225
220226#: Greeter/PassphraseLockscreen.qml:59
221227msgid "Hello"
@@ -252,4 +258,4 @@ msgstr "No hi ha res que coincideixi amb la cerca"
252258#: Shell.qml:429
253259#, qt-format
254260msgid "Please enter %1"
255−msgstr ""
261+msgstr "Introduïu %1"
po/en_AU.po+27−26
@@ -8,15 +8,15 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-08-27 13:36-0400\n"
11−"PO-Revision-Date: 2013-06-27 01:13+0000\n"
12−"Last-Translator: Jackson Doak <Doak.jackson@gmail.com>\n"
11+"PO-Revision-Date: 2013-09-28 07:46+0000\n"
12+"Last-Translator: Jared Norris <jarednorris@ubuntu.com>\n"
1313"Language-Team: English (Australia) <en_AU@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-08-30 05:37+0000\n"
19−"X-Generator: Launchpad (build 16750)\n"
18+"X-Launchpad-Export-Date: 2013-09-29 06:18+0000\n"
19+"X-Generator: Launchpad (build 16774)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -88,47 +88,48 @@ msgstr "YouTube"
8888
8989#: Components/EdgeDemoOverlay.qml:145
9090msgid "Skip intro"
91−msgstr ""
91+msgstr "Skip intro"
9292
9393#: Components/EdgeDemo.qml:98
9494msgid "Right edge"
95−msgstr ""
95+msgstr "Right edge"
9696
9797#: Components/EdgeDemo.qml:99
9898msgid "Try swiping from the right edge to unlock the phone"
99−msgstr ""
99+msgstr "Try swiping from the right edge to unlock the phone"
100100
101101#: Components/EdgeDemo.qml:135
102102msgid "Top edge"
103−msgstr ""
103+msgstr "Top edge"
104104
105105#: Components/EdgeDemo.qml:136
106106msgid "Try swiping from the top edge to access the indicators"
107−msgstr ""
107+msgstr "Try swiping from the top edge to access the indicators"
108108
109109#: Components/EdgeDemo.qml:161
110110msgid "Close"
111−msgstr ""
111+msgstr "Close"
112112
113113#: Components/EdgeDemo.qml:162
114114msgid "Swipe up again to close the settings screen"
115−msgstr ""
115+msgstr "Swipe up again to close the settings screen"
116116
117117#: Components/EdgeDemo.qml:189
118118msgid "Left edge"
119−msgstr ""
119+msgstr "Left edge"
120120
121121#: Components/EdgeDemo.qml:190
122122msgid "Swipe from the left to reveal the launcher for quick access to apps"
123−msgstr ""
123+msgstr "Swipe from the left to reveal the launcher for quick access to apps"
124124
125125#: Components/EdgeDemo.qml:217
126126msgid "Well done"
127−msgstr ""
127+msgstr "Well done"
128128
129129#: Components/EdgeDemo.qml:218
130130msgid "You have now mastered the edge gestures and can start using the phone"
131131msgstr ""
132+"You have now mastered the edge gestures and can start using the phone"
132133
133134#: Components/PageHeader.qml:298
134135msgid "Recent searches"
@@ -138,35 +139,35 @@ msgstr "Recent searches"
138139#: Dash/Apps/AppInfo.qml:73
139140#, qt-format
140141msgid "(%1)"
141−msgstr ""
142+msgstr "(%1)"
142143
143144#. TRANSLATORS: Number of persons who wrote reviews for this app
144145#: Dash/Apps/AppInfo.qml:85
145146#, qt-format
146147msgid "%1 review"
147148msgid_plural "%1 reviews"
148−msgstr[0] ""
149−msgstr[1] ""
149+msgstr[0] "%1 review"
150+msgstr[1] "%1 reviews"
150151
151152#: Dash/Apps/AppPreview.qml:175
152153msgid "Rate this"
153−msgstr ""
154+msgstr "Rate this"
154155
155156#: Dash/Apps/AppReviews.qml:72
156157msgid "Add a review"
157−msgstr ""
158+msgstr "Add a review"
158159
159160#: Dash/Apps/AppReviews.qml:84
160161msgid "Review"
161−msgstr ""
162+msgstr "Review"
162163
163164#: Dash/Apps/AppReviews.qml:118
164165msgid "Send"
165−msgstr ""
166+msgstr "Send"
166167
167168#: Dash/Apps/AppReviews.qml:136
168169msgid "Comments:"
169−msgstr ""
170+msgstr "Comments:"
170171
171172#: Dash/DashMusic.qml:27 Dash/DashVideos.qml:28
172173msgid "Featured"
@@ -210,16 +211,16 @@ msgstr "Author:"
210211
211212#: Greeter/Lockscreen.qml:134
212213msgid "Emergency Call"
213−msgstr ""
214+msgstr "Emergency Call"
214215
215216#: Greeter/PassphraseLockscreen.qml:59
216217#, qt-format
217218msgid "Hello %1"
218−msgstr ""
219+msgstr "Hello %1"
219220
220221#: Greeter/PassphraseLockscreen.qml:59
221222msgid "Hello"
222−msgstr ""
223+msgstr "Hello"
223224
224225#: Hud/HudParametrizedActionsPage.qml:132
225226msgid "Confirm"
@@ -252,4 +253,4 @@ msgstr "Sorry, there is nothing that matches your search."
252253#: Shell.qml:429
253254#, qt-format
254255msgid "Please enter %1"
255−msgstr ""
256+msgstr "Please enter %1"
po/es.po+5−5
@@ -8,15 +8,15 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-08-27 13:36-0400\n"
11−"PO-Revision-Date: 2013-09-04 22:12+0000\n"
12−"Last-Translator: Adolfo Jayme Barrientos <fitoschido@gmail.com>\n"
11+"PO-Revision-Date: 2013-09-28 07:35+0000\n"
12+"Last-Translator: Paco Molinero <paco@byasl.com>\n"
1313"Language-Team: Spanish <es@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-09-05 05:35+0000\n"
19−"X-Generator: Launchpad (build 16758)\n"
18+"X-Launchpad-Export-Date: 2013-09-29 06:18+0000\n"
19+"X-Generator: Launchpad (build 16774)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -48,7 +48,7 @@ msgstr "GMail"
4848
4949#: Applications/applications.js:62
5050msgid "Weather"
51−msgstr "Metereología"
51+msgstr "Meteorología"
5252
5353#: Applications/applications.js:68
5454msgid "Notepad"
po/fi.po+15−15
@@ -8,15 +8,15 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-08-27 13:36-0400\n"
11−"PO-Revision-Date: 2013-08-23 16:15+0000\n"
12−"Last-Translator: Timo Jyrinki <timo.jyrinki@canonical.com>\n"
11+"PO-Revision-Date: 2013-09-26 09:25+0000\n"
12+"Last-Translator: Jiri Grönroos <Unknown>\n"
1313"Language-Team: Finnish <fi@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-08-30 05:37+0000\n"
19−"X-Generator: Launchpad (build 16750)\n"
18+"X-Launchpad-Export-Date: 2013-09-27 06:43+0000\n"
19+"X-Generator: Launchpad (build 16774)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -88,47 +88,47 @@ msgstr "YouTube"
8888
8989#: Components/EdgeDemoOverlay.qml:145
9090msgid "Skip intro"
91−msgstr ""
91+msgstr "Ohita esittely"
9292
9393#: Components/EdgeDemo.qml:98
9494msgid "Right edge"
95−msgstr ""
95+msgstr "Oikea reuna"
9696
9797#: Components/EdgeDemo.qml:99
9898msgid "Try swiping from the right edge to unlock the phone"
99−msgstr ""
99+msgstr "Vedä oikealta avataksesi puhelimen lukituksen"
100100
101101#: Components/EdgeDemo.qml:135
102102msgid "Top edge"
103−msgstr ""
103+msgstr "Yläreuna"
104104
105105#: Components/EdgeDemo.qml:136
106106msgid "Try swiping from the top edge to access the indicators"
107−msgstr ""
107+msgstr "Vedä yläreunasta käyttääksesi ilmaisimia"
108108
109109#: Components/EdgeDemo.qml:161
110110msgid "Close"
111−msgstr ""
111+msgstr "Sulje"
112112
113113#: Components/EdgeDemo.qml:162
114114msgid "Swipe up again to close the settings screen"
115−msgstr ""
115+msgstr "Vedä uudestaan sulkeaksesi asetusnäkymän"
116116
117117#: Components/EdgeDemo.qml:189
118118msgid "Left edge"
119−msgstr ""
119+msgstr "Vasen reuna"
120120
121121#: Components/EdgeDemo.qml:190
122122msgid "Swipe from the left to reveal the launcher for quick access to apps"
123−msgstr ""
123+msgstr "Vedä vasemmalta saattaaksesi sovellusten käynnistimen esiin"
124124
125125#: Components/EdgeDemo.qml:217
126126msgid "Well done"
127−msgstr ""
127+msgstr "Hyvin tehty"
128128
129129#: Components/EdgeDemo.qml:218
130130msgid "You have now mastered the edge gestures and can start using the phone"
131−msgstr ""
131+msgstr "Hallitset nyt reunaeleet, joten voit aloittaa puhelimen käytön"
132132
133133#: Components/PageHeader.qml:298
134134msgid "Recent searches"
po/gl.po+29−29
@@ -8,99 +8,99 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-08-27 13:36-0400\n"
11−"PO-Revision-Date: 2013-06-27 03:38+0000\n"
12−"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
11+"PO-Revision-Date: 2013-09-29 11:14+0000\n"
12+"Last-Translator: Marcos Lans <Unknown>\n"
1313"Language-Team: Galician <gl@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-08-30 05:37+0000\n"
19−"X-Generator: Launchpad (build 16750)\n"
18+"X-Launchpad-Export-Date: 2013-09-30 05:57+0000\n"
19+"X-Generator: Launchpad (build 16774)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
23−msgstr ""
23+msgstr "Teléfono"
2424
2525#: Applications/applications.js:29
2626msgid "Camera"
27−msgstr ""
27+msgstr "Cámara"
2828
2929#: Applications/applications.js:35
3030msgid "Gallery"
31−msgstr ""
31+msgstr "Galería"
3232
3333#: Applications/applications.js:40
3434msgid "Facebook"
35−msgstr ""
35+msgstr "Facebook"
3636
3737#: Applications/applications.js:46
3838msgid "Browser"
39−msgstr ""
39+msgstr "Navegador"
4040
4141#: Applications/applications.js:51
4242msgid "Twitter"
43−msgstr ""
43+msgstr "Twitter"
4444
4545#: Applications/applications.js:57
4646msgid "GMail"
47−msgstr ""
47+msgstr "GMail"
4848
4949#: Applications/applications.js:62
5050msgid "Weather"
51−msgstr ""
51+msgstr "O tempo"
5252
5353#: Applications/applications.js:68
5454msgid "Notepad"
55−msgstr ""
55+msgstr "Bloc de notas"
5656
5757#: Applications/applications.js:74
5858msgid "Calendar"
59−msgstr ""
59+msgstr "Calendario"
6060
6161#: Applications/applications.js:80
6262msgid "Media Player"
63−msgstr ""
63+msgstr "Reprodutor multimedia"
6464
6565#: Applications/applications.js:86
6666msgid "Evernote"
67−msgstr ""
67+msgstr "Evernote"
6868
6969#: Applications/applications.js:91
7070msgid "Map"
71−msgstr ""
71+msgstr "Mapa"
7272
7373#: Applications/applications.js:96
7474msgid "Pinterest"
75−msgstr ""
75+msgstr "Pinterest"
7676
7777#: Applications/applications.js:101
7878msgid "SoundCloud"
79−msgstr ""
79+msgstr "SoundCloud"
8080
8181#: Applications/applications.js:106
8282msgid "Wikipedia"
83−msgstr ""
83+msgstr "Wikipedia"
8484
8585#: Applications/applications.js:111
8686msgid "YouTube"
87−msgstr ""
87+msgstr "YouTube"
8888
8989#: Components/EdgeDemoOverlay.qml:145
9090msgid "Skip intro"
91−msgstr ""
91+msgstr "Saltar introdución"
9292
9393#: Components/EdgeDemo.qml:98
9494msgid "Right edge"
95−msgstr ""
95+msgstr "Bordo dereito"
9696
9797#: Components/EdgeDemo.qml:99
9898msgid "Try swiping from the right edge to unlock the phone"
99−msgstr ""
99+msgstr "Probe a arrastrar desde o bordo dereito para desbloquear o teléfono"
100100
101101#: Components/EdgeDemo.qml:135
102102msgid "Top edge"
103−msgstr ""
103+msgstr "Bordo superior"
104104
105105#: Components/EdgeDemo.qml:136
106106msgid "Try swiping from the top edge to access the indicators"
@@ -108,7 +108,7 @@ msgstr ""
108108
109109#: Components/EdgeDemo.qml:161
110110msgid "Close"
111−msgstr ""
111+msgstr "Pechar"
112112
113113#: Components/EdgeDemo.qml:162
114114msgid "Swipe up again to close the settings screen"
@@ -116,7 +116,7 @@ msgstr ""
116116
117117#: Components/EdgeDemo.qml:189
118118msgid "Left edge"
119−msgstr ""
119+msgstr "Bordo esquerdo"
120120
121121#: Components/EdgeDemo.qml:190
122122msgid "Swipe from the left to reveal the launcher for quick access to apps"
@@ -124,7 +124,7 @@ msgstr ""
124124
125125#: Components/EdgeDemo.qml:217
126126msgid "Well done"
127−msgstr ""
127+msgstr "Ben feito"
128128
129129#: Components/EdgeDemo.qml:218
130130msgid "You have now mastered the edge gestures and can start using the phone"
@@ -138,7 +138,7 @@ msgstr "Buscas recentes"
138138#: Dash/Apps/AppInfo.qml:73
139139#, qt-format
140140msgid "(%1)"
141−msgstr ""
141+msgstr "(%1)"
142142
143143#. TRANSLATORS: Number of persons who wrote reviews for this app
144144#: Dash/Apps/AppInfo.qml:85
po/is.ponew file+256
@@ -0,0 +1,256 @@
1+# Icelandic translation for unity8
2+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
3+# This file is distributed under the same license as the unity8 package.
4+# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
5+#
6+msgid ""
7+msgstr ""
8+"Project-Id-Version: unity8\n"
9+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10+"POT-Creation-Date: 2013-08-27 13:36-0400\n"
11+"PO-Revision-Date: 2013-09-18 16:22+0000\n"
12+"Last-Translator: Andri Thorlacius <Unknown>\n"
13+"Language-Team: Icelandic <is@li.org>\n"
14+"MIME-Version: 1.0\n"
15+"Content-Type: text/plain; charset=UTF-8\n"
16+"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
18+"X-Launchpad-Export-Date: 2013-09-19 05:14+0000\n"
19+"X-Generator: Launchpad (build 16765)\n"
20+
21+#: Applications/applications.js:23
22+msgid "Phone"
23+msgstr "Sími"
24+
25+#: Applications/applications.js:29
26+msgid "Camera"
27+msgstr "Myndavél"
28+
29+#: Applications/applications.js:35
30+msgid "Gallery"
31+msgstr "Myndasafn"
32+
33+#: Applications/applications.js:40
34+msgid "Facebook"
35+msgstr "Facebook"
36+
37+#: Applications/applications.js:46
38+msgid "Browser"
39+msgstr "Vafri"
40+
41+#: Applications/applications.js:51
42+msgid "Twitter"
43+msgstr "Twitter"
44+
45+#: Applications/applications.js:57
46+msgid "GMail"
47+msgstr "GMail"
48+
49+#: Applications/applications.js:62
50+msgid "Weather"
51+msgstr "Veður"
52+
53+#: Applications/applications.js:68
54+msgid "Notepad"
55+msgstr "Skrifblokk"
56+
57+#: Applications/applications.js:74
58+msgid "Calendar"
59+msgstr "Dagatal"
60+
61+#: Applications/applications.js:80
62+msgid "Media Player"
63+msgstr "Margmiðlunarspilari"
64+
65+#: Applications/applications.js:86
66+msgid "Evernote"
67+msgstr "Evernote"
68+
69+#: Applications/applications.js:91
70+msgid "Map"
71+msgstr "Kort"
72+
73+#: Applications/applications.js:96
74+msgid "Pinterest"
75+msgstr "Pinterest"
76+
77+#: Applications/applications.js:101
78+msgid "SoundCloud"
79+msgstr "SoundCloud"
80+
81+#: Applications/applications.js:106
82+msgid "Wikipedia"
83+msgstr "Wikipedia"
84+
85+#: Applications/applications.js:111
86+msgid "YouTube"
87+msgstr "YouTube"
88+
89+#: Components/EdgeDemoOverlay.qml:145
90+msgid "Skip intro"
91+msgstr "Hoppa yfir kynningu"
92+
93+#: Components/EdgeDemo.qml:98
94+msgid "Right edge"
95+msgstr "Hægri brún"
96+
97+#: Components/EdgeDemo.qml:99
98+msgid "Try swiping from the right edge to unlock the phone"
99+msgstr ""
100+"Prufaðu að renna puttanum frá hægri brúninni til að aflæsa símanum þínum."
101+
102+#: Components/EdgeDemo.qml:135
103+msgid "Top edge"
104+msgstr "Efri brún"
105+
106+#: Components/EdgeDemo.qml:136
107+msgid "Try swiping from the top edge to access the indicators"
108+msgstr ""
109+
110+#: Components/EdgeDemo.qml:161
111+msgid "Close"
112+msgstr "Loka"
113+
114+#: Components/EdgeDemo.qml:162
115+msgid "Swipe up again to close the settings screen"
116+msgstr ""
117+
118+#: Components/EdgeDemo.qml:189
119+msgid "Left edge"
120+msgstr "Vinstri brún"
121+
122+#: Components/EdgeDemo.qml:190
123+msgid "Swipe from the left to reveal the launcher for quick access to apps"
124+msgstr ""
125+
126+#: Components/EdgeDemo.qml:217
127+msgid "Well done"
128+msgstr "Vel gert"
129+
130+#: Components/EdgeDemo.qml:218
131+msgid "You have now mastered the edge gestures and can start using the phone"
132+msgstr ""
133+
134+#: Components/PageHeader.qml:298
135+msgid "Recent searches"
136+msgstr "Nýlegar leitir"
137+
138+#. TRANSLATORS: Number of persons who rated this app
139+#: Dash/Apps/AppInfo.qml:73
140+#, qt-format
141+msgid "(%1)"
142+msgstr "(%1)"
143+
144+#. TRANSLATORS: Number of persons who wrote reviews for this app
145+#: Dash/Apps/AppInfo.qml:85
146+#, qt-format
147+msgid "%1 review"
148+msgid_plural "%1 reviews"
149+msgstr[0] "%1 ummæli"
150+msgstr[1] "%1 ummæli"
151+
152+#: Dash/Apps/AppPreview.qml:175
153+msgid "Rate this"
154+msgstr "Gefa þessu einkunn"
155+
156+#: Dash/Apps/AppReviews.qml:72
157+msgid "Add a review"
158+msgstr "Gefa umsögn"
159+
160+#: Dash/Apps/AppReviews.qml:84
161+msgid "Review"
162+msgstr "Umsögn"
163+
164+#: Dash/Apps/AppReviews.qml:118
165+msgid "Send"
166+msgstr "Senda"
167+
168+#: Dash/Apps/AppReviews.qml:136
169+msgid "Comments:"
170+msgstr "Athugasemdir:"
171+
172+#: Dash/DashMusic.qml:27 Dash/DashVideos.qml:28
173+msgid "Featured"
174+msgstr "Efst á baugi"
175+
176+#: Dash/DashMusic.qml:28 Dash/DashVideos.qml:29
177+msgid "Recent"
178+msgstr "Nýlegt"
179+
180+#: Dash/DashMusic.qml:29 Dash/DashVideos.qml:30
181+msgid "New Releases"
182+msgstr "Nýjar Útgáfur"
183+
184+#: Dash/DashMusic.qml:30
185+msgid "Top Charting"
186+msgstr "Topp Listi"
187+
188+#: Dash/DashMusic.qml:91
189+msgid "Music"
190+msgstr "Tónlist"
191+
192+#: Dash/DashVideos.qml:31
193+msgid "Popular Online"
194+msgstr "Vinsælt á Netinu"
195+
196+#: Dash/DashVideos.qml:146
197+msgid "Videos"
198+msgstr "Myndbönd"
199+
200+#: Dash/Video/VideoPreview.qml:130
201+msgid "Directed by:"
202+msgstr "Leikstýrt af:"
203+
204+#: Dash/Video/VideoPreview.qml:153
205+msgid "Starring:"
206+msgstr "Meðal leikara eru:"
207+
208+#: Dash/Video/VideoPreview.qml:176
209+msgid "Author:"
210+msgstr "Höfundur:"
211+
212+#: Greeter/Lockscreen.qml:134
213+msgid "Emergency Call"
214+msgstr "Neyðarsímtal"
215+
216+#: Greeter/PassphraseLockscreen.qml:59
217+#, qt-format
218+msgid "Hello %1"
219+msgstr "Hæ %1"
220+
221+#: Greeter/PassphraseLockscreen.qml:59
222+msgid "Hello"
223+msgstr "Hæ"
224+
225+#: Hud/HudParametrizedActionsPage.qml:132
226+msgid "Confirm"
227+msgstr "Staðfesta"
228+
229+#: Hud/Hud.qml:61 Hud/Hud.qml:99 Hud/Hud.qml:372
230+msgid "Type or say a command"
231+msgstr "Skrifaðu eða segðu eitthvað"
232+
233+#: Hud/Hud.qml:84
234+msgid "Loading. Please Wait..."
235+msgstr "Hleð. Vinsamlegast Bíðið..."
236+
237+#: Hud/Hud.qml:89
238+msgid "Speak Now..."
239+msgstr "Talaðu Núna..."
240+
241+#: Hud/Hud.qml:94
242+msgid "Speaking..."
243+msgstr "Tala..."
244+
245+#: Panel/SearchIndicator.qml:27
246+msgid "Search"
247+msgstr "Leita"
248+
249+#: plugins/Unity/scope.cpp:317
250+msgid "Sorry, there is nothing that matches your search."
251+msgstr "Því miður, það var ekkert sem passaði við leitarorðið þitt."
252+
253+#: Shell.qml:429
254+#, qt-format
255+msgid "Please enter %1"
256+msgstr ""
po/it.po+55−48
@@ -8,127 +8,134 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-08-27 13:36-0400\n"
11−"PO-Revision-Date: 2013-06-27 05:14+0000\n"
12−"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
11+"PO-Revision-Date: 2013-09-28 10:05+0000\n"
12+"Last-Translator: Claudio Arseni <claudio.arseni@gmail.com>\n"
1313"Language-Team: Italian <it@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-08-30 05:37+0000\n"
19−"X-Generator: Launchpad (build 16750)\n"
18+"X-Launchpad-Export-Date: 2013-09-29 06:18+0000\n"
19+"X-Generator: Launchpad (build 16774)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
23−msgstr ""
23+msgstr "Telefono"
2424
2525#: Applications/applications.js:29
2626msgid "Camera"
27−msgstr ""
27+msgstr "Fotocamera"
2828
2929#: Applications/applications.js:35
3030msgid "Gallery"
31−msgstr ""
31+msgstr "Galleria"
3232
3333#: Applications/applications.js:40
3434msgid "Facebook"
35−msgstr ""
35+msgstr "Facebook"
3636
3737#: Applications/applications.js:46
3838msgid "Browser"
39−msgstr ""
39+msgstr "Browser"
4040
4141#: Applications/applications.js:51
4242msgid "Twitter"
43−msgstr ""
43+msgstr "Twitter"
4444
4545#: Applications/applications.js:57
4646msgid "GMail"
47−msgstr ""
47+msgstr "GMail"
4848
4949#: Applications/applications.js:62
5050msgid "Weather"
51−msgstr ""
51+msgstr "Meteo"
5252
5353#: Applications/applications.js:68
5454msgid "Notepad"
55−msgstr ""
55+msgstr "Blocco note"
5656
5757#: Applications/applications.js:74
5858msgid "Calendar"
59−msgstr ""
59+msgstr "Calendario"
6060
6161#: Applications/applications.js:80
6262msgid "Media Player"
63−msgstr ""
63+msgstr "Riproduttore multimediale"
6464
6565#: Applications/applications.js:86
6666msgid "Evernote"
67−msgstr ""
67+msgstr "Evernote"
6868
6969#: Applications/applications.js:91
7070msgid "Map"
71−msgstr ""
71+msgstr "Mappa"
7272
7373#: Applications/applications.js:96
7474msgid "Pinterest"
75−msgstr ""
75+msgstr "Pinterest"
7676
7777#: Applications/applications.js:101
7878msgid "SoundCloud"
79−msgstr ""
79+msgstr "SoundCloud"
8080
8181#: Applications/applications.js:106
8282msgid "Wikipedia"
83−msgstr ""
83+msgstr "Wikipedia"
8484
8585#: Applications/applications.js:111
8686msgid "YouTube"
87−msgstr ""
87+msgstr "YouTube"
8888
8989#: Components/EdgeDemoOverlay.qml:145
9090msgid "Skip intro"
91−msgstr ""
91+msgstr "Salta introduzione"
9292
9393#: Components/EdgeDemo.qml:98
9494msgid "Right edge"
95−msgstr ""
95+msgstr "Bordo destro"
9696
9797#: Components/EdgeDemo.qml:99
9898msgid "Try swiping from the right edge to unlock the phone"
99−msgstr ""
99+msgstr "Provare a far scorrere dal bordo destro per sbloccare il telefono"
100100
101101#: Components/EdgeDemo.qml:135
102102msgid "Top edge"
103−msgstr ""
103+msgstr "Bordo superiore"
104104
105105#: Components/EdgeDemo.qml:136
106106msgid "Try swiping from the top edge to access the indicators"
107107msgstr ""
108+"Provare a far scorrere dal bordo in alto per accedere agli indicatori"
108109
109110#: Components/EdgeDemo.qml:161
110111msgid "Close"
111−msgstr ""
112+msgstr "Chiudi"
112113
113114#: Components/EdgeDemo.qml:162
114115msgid "Swipe up again to close the settings screen"
115116msgstr ""
117+"Far scorrere verso l'alto nuovamente per chiudere la schermata delle "
118+"impostazioni"
116119
117120#: Components/EdgeDemo.qml:189
118121msgid "Left edge"
119−msgstr ""
122+msgstr "Bordo sinistro"
120123
121124#: Components/EdgeDemo.qml:190
122125msgid "Swipe from the left to reveal the launcher for quick access to apps"
123126msgstr ""
127+"Far scorrere il bordo sinistro per mostrare il Launcher e avere un rapido "
128+"accesso alle applicazioni"
124129
125130#: Components/EdgeDemo.qml:217
126131msgid "Well done"
127−msgstr ""
132+msgstr "Ben fatto"
128133
129134#: Components/EdgeDemo.qml:218
130135msgid "You have now mastered the edge gestures and can start using the phone"
131136msgstr ""
137+"I gesti sui bordi dello schermo sono ora configurato ed è possibile usare il "
138+"telefono"
132139
133140#: Components/PageHeader.qml:298
134141msgid "Recent searches"
@@ -138,51 +145,51 @@ msgstr "Ricerche recenti"
138145#: Dash/Apps/AppInfo.qml:73
139146#, qt-format
140147msgid "(%1)"
141−msgstr ""
148+msgstr "(%1)"
142149
143150#. TRANSLATORS: Number of persons who wrote reviews for this app
144151#: Dash/Apps/AppInfo.qml:85
145152#, qt-format
146153msgid "%1 review"
147154msgid_plural "%1 reviews"
148−msgstr[0] ""
149−msgstr[1] ""
155+msgstr[0] "%1 recensione"
156+msgstr[1] "%1 recensioni"
150157
151158#: Dash/Apps/AppPreview.qml:175
152159msgid "Rate this"
153−msgstr ""
160+msgstr "Valuta"
154161
155162#: Dash/Apps/AppReviews.qml:72
156163msgid "Add a review"
157−msgstr ""
164+msgstr "Aggiungi una recensione"
158165
159166#: Dash/Apps/AppReviews.qml:84
160167msgid "Review"
161−msgstr ""
168+msgstr "Recensisci"
162169
163170#: Dash/Apps/AppReviews.qml:118
164171msgid "Send"
165−msgstr ""
172+msgstr "Invia"
166173
167174#: Dash/Apps/AppReviews.qml:136
168175msgid "Comments:"
169−msgstr ""
176+msgstr "Commenti:"
170177
171178#: Dash/DashMusic.qml:27 Dash/DashVideos.qml:28
172179msgid "Featured"
173−msgstr ""
180+msgstr "In evidenza"
174181
175182#: Dash/DashMusic.qml:28 Dash/DashVideos.qml:29
176183msgid "Recent"
177−msgstr ""
184+msgstr "Recenti"
178185
179186#: Dash/DashMusic.qml:29 Dash/DashVideos.qml:30
180187msgid "New Releases"
181−msgstr ""
188+msgstr "Nuovi rilasci"
182189
183190#: Dash/DashMusic.qml:30
184191msgid "Top Charting"
185−msgstr ""
192+msgstr "Più votate"
186193
187194#: Dash/DashMusic.qml:91
188195msgid "Music"
@@ -190,7 +197,7 @@ msgstr "Musica"
190197
191198#: Dash/DashVideos.qml:31
192199msgid "Popular Online"
193−msgstr ""
200+msgstr "Popolari online"
194201
195202#: Dash/DashVideos.qml:146
196203msgid "Videos"
@@ -198,28 +205,28 @@ msgstr "Video"
198205
199206#: Dash/Video/VideoPreview.qml:130
200207msgid "Directed by:"
201−msgstr ""
208+msgstr "Diretto da:"
202209
203210#: Dash/Video/VideoPreview.qml:153
204211msgid "Starring:"
205−msgstr ""
212+msgstr "Valutazioni:"
206213
207214#: Dash/Video/VideoPreview.qml:176
208215msgid "Author:"
209−msgstr ""
216+msgstr "Autore:"
210217
211218#: Greeter/Lockscreen.qml:134
212219msgid "Emergency Call"
213−msgstr ""
220+msgstr "Chiamata di emergenza"
214221
215222#: Greeter/PassphraseLockscreen.qml:59
216223#, qt-format
217224msgid "Hello %1"
218−msgstr ""
225+msgstr "Ciao %1"
219226
220227#: Greeter/PassphraseLockscreen.qml:59
221228msgid "Hello"
222−msgstr ""
229+msgstr "Ciao"
223230
224231#: Hud/HudParametrizedActionsPage.qml:132
225232msgid "Confirm"
@@ -252,4 +259,4 @@ msgstr "Nessun risultato corrispondente alla ricerca."
252259#: Shell.qml:429
253260#, qt-format
254261msgid "Please enter %1"
255−msgstr ""
262+msgstr "Inserire %1"
po/lv.po+21−21
@@ -8,59 +8,59 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-08-27 13:36-0400\n"
11−"PO-Revision-Date: 2013-06-27 06:31+0000\n"
12−"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
11+"PO-Revision-Date: 2013-09-28 16:29+0000\n"
12+"Last-Translator: Jānis-Marks Gailis <jeanmarc.gailis@gmail.com>\n"
1313"Language-Team: Latvian <lv@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2;\n"
18−"X-Launchpad-Export-Date: 2013-08-30 05:37+0000\n"
19−"X-Generator: Launchpad (build 16750)\n"
18+"X-Launchpad-Export-Date: 2013-09-29 06:18+0000\n"
19+"X-Generator: Launchpad (build 16774)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
23−msgstr ""
23+msgstr "Tālrunis"
2424
2525#: Applications/applications.js:29
2626msgid "Camera"
27−msgstr ""
27+msgstr "Fotokamera"
2828
2929#: Applications/applications.js:35
3030msgid "Gallery"
31−msgstr ""
31+msgstr "Galerija"
3232
3333#: Applications/applications.js:40
3434msgid "Facebook"
35−msgstr ""
35+msgstr "Facebook"
3636
3737#: Applications/applications.js:46
3838msgid "Browser"
39−msgstr ""
39+msgstr "Pārlūkprogramma"
4040
4141#: Applications/applications.js:51
4242msgid "Twitter"
43−msgstr ""
43+msgstr "Twitter"
4444
4545#: Applications/applications.js:57
4646msgid "GMail"
47−msgstr ""
47+msgstr "GMail"
4848
4949#: Applications/applications.js:62
5050msgid "Weather"
51−msgstr ""
51+msgstr "Laikapstākļi"
5252
5353#: Applications/applications.js:68
5454msgid "Notepad"
55−msgstr ""
55+msgstr "Bloknots"
5656
5757#: Applications/applications.js:74
5858msgid "Calendar"
59−msgstr ""
59+msgstr "Kalendārs"
6060
6161#: Applications/applications.js:80
6262msgid "Media Player"
63−msgstr ""
63+msgstr "Mēdiju Atskaņotājs"
6464
6565#: Applications/applications.js:86
6666msgid "Evernote"
@@ -68,23 +68,23 @@ msgstr ""
6868
6969#: Applications/applications.js:91
7070msgid "Map"
71−msgstr ""
71+msgstr "Karte"
7272
7373#: Applications/applications.js:96
7474msgid "Pinterest"
75−msgstr ""
75+msgstr "Pinterest"
7676
7777#: Applications/applications.js:101
7878msgid "SoundCloud"
79−msgstr ""
79+msgstr "SoundCloud"
8080
8181#: Applications/applications.js:106
8282msgid "Wikipedia"
83−msgstr ""
83+msgstr "Vikipēdija"
8484
8585#: Applications/applications.js:111
8686msgid "YouTube"
87−msgstr ""
87+msgstr "YouTube"
8888
8989#: Components/EdgeDemoOverlay.qml:145
9090msgid "Skip intro"
@@ -92,7 +92,7 @@ msgstr ""
9292
9393#: Components/EdgeDemo.qml:98
9494msgid "Right edge"
95−msgstr ""
95+msgstr "Labā mala"
9696
9797#: Components/EdgeDemo.qml:99
9898msgid "Try swiping from the right edge to unlock the phone"
po/ru.po+32−26
@@ -8,16 +8,16 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-08-27 13:36-0400\n"
11−"PO-Revision-Date: 2013-06-28 06:40+0000\n"
12−"Last-Translator: Eugene Marshal <Unknown>\n"
11+"PO-Revision-Date: 2013-09-29 09:11+0000\n"
12+"Last-Translator: Устин <ustinershovskiy@yandex.ru>\n"
1313"Language-Team: Russian <ru@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
1818"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2013-08-30 05:37+0000\n"
20−"X-Generator: Launchpad (build 16750)\n"
19+"X-Launchpad-Export-Date: 2013-09-30 05:57+0000\n"
20+"X-Generator: Launchpad (build 16774)\n"
2121
2222#: Applications/applications.js:23
2323msgid "Phone"
@@ -89,47 +89,54 @@ msgstr "YouTube"
8989
9090#: Components/EdgeDemoOverlay.qml:145
9191msgid "Skip intro"
92−msgstr ""
92+msgstr "Пропустить обучение"
9393
9494#: Components/EdgeDemo.qml:98
9595msgid "Right edge"
96−msgstr ""
96+msgstr "Правый край"
9797
9898#: Components/EdgeDemo.qml:99
9999msgid "Try swiping from the right edge to unlock the phone"
100100msgstr ""
101+"Попробуйте переместить палец от правого края к левому для разблокировки "
102+"устройства"
101103
102104#: Components/EdgeDemo.qml:135
103105msgid "Top edge"
104−msgstr ""
106+msgstr "Верхний край"
105107
106108#: Components/EdgeDemo.qml:136
107109msgid "Try swiping from the top edge to access the indicators"
108110msgstr ""
111+"Попробуйте переместить палец от верхнего края вниз для доступа к индикаторам"
109112
110113#: Components/EdgeDemo.qml:161
111114msgid "Close"
112−msgstr ""
115+msgstr "Закрыть"
113116
114117#: Components/EdgeDemo.qml:162
115118msgid "Swipe up again to close the settings screen"
116−msgstr ""
119+msgstr "Снова переместите палец вверх для закрытия экрана настроек"
117120
118121#: Components/EdgeDemo.qml:189
119122msgid "Left edge"
120−msgstr ""
123+msgstr "Левый край"
121124
122125#: Components/EdgeDemo.qml:190
123126msgid "Swipe from the left to reveal the launcher for quick access to apps"
124127msgstr ""
128+"Переместите палец от левого края вправо для открытия лаунчера для быстрого "
129+"доступа к приложениям"
125130
126131#: Components/EdgeDemo.qml:217
127132msgid "Well done"
128−msgstr ""
133+msgstr "Великолепно"
129134
130135#: Components/EdgeDemo.qml:218
131136msgid "You have now mastered the edge gestures and can start using the phone"
132137msgstr ""
138+"Теперь вы научились экранным жестам и можете приступить к использованию "
139+"устройства"
133140
134141#: Components/PageHeader.qml:298
135142msgid "Recent searches"
@@ -139,39 +146,38 @@ msgstr "Последние поисковые запросы"
139146#: Dash/Apps/AppInfo.qml:73
140147#, qt-format
141148msgid "(%1)"
142−msgstr ""
149+msgstr "(%1)"
143150
144151#. TRANSLATORS: Number of persons who wrote reviews for this app
145152#: Dash/Apps/AppInfo.qml:85
146153#, qt-format
147154msgid "%1 review"
148155msgid_plural "%1 reviews"
149−msgstr[0] ""
150−msgstr[1] ""
156+msgstr[0] "%1 отзыв"
151157
152158#: Dash/Apps/AppPreview.qml:175
153159msgid "Rate this"
154−msgstr ""
160+msgstr "Оцените это"
155161
156162#: Dash/Apps/AppReviews.qml:72
157163msgid "Add a review"
158−msgstr ""
164+msgstr "Добавьте отзыв"
159165
160166#: Dash/Apps/AppReviews.qml:84
161167msgid "Review"
162−msgstr ""
168+msgstr "Отзыв"
163169
164170#: Dash/Apps/AppReviews.qml:118
165171msgid "Send"
166−msgstr ""
172+msgstr "Отправить"
167173
168174#: Dash/Apps/AppReviews.qml:136
169175msgid "Comments:"
170−msgstr ""
176+msgstr "Комментарии:"
171177
172178#: Dash/DashMusic.qml:27 Dash/DashVideos.qml:28
173179msgid "Featured"
174−msgstr ""
180+msgstr "Рекомендованное"
175181
176182#: Dash/DashMusic.qml:28 Dash/DashVideos.qml:29
177183msgid "Recent"
@@ -183,7 +189,7 @@ msgstr "Новые релизы"
183189
184190#: Dash/DashMusic.qml:30
185191msgid "Top Charting"
186−msgstr ""
192+msgstr "Наиболее популярное"
187193
188194#: Dash/DashMusic.qml:91
189195msgid "Music"
@@ -191,7 +197,7 @@ msgstr "Музыка"
191197
192198#: Dash/DashVideos.qml:31
193199msgid "Popular Online"
194−msgstr ""
200+msgstr "Популярное в Интернете"
195201
196202#: Dash/DashVideos.qml:146
197203msgid "Videos"
@@ -211,20 +217,20 @@ msgstr "Автор:"
211217
212218#: Greeter/Lockscreen.qml:134
213219msgid "Emergency Call"
214−msgstr ""
220+msgstr "Экстренный вызов"
215221
216222#: Greeter/PassphraseLockscreen.qml:59
217223#, qt-format
218224msgid "Hello %1"
219−msgstr ""
225+msgstr "Привет, %1"
220226
221227#: Greeter/PassphraseLockscreen.qml:59
222228msgid "Hello"
223−msgstr ""
229+msgstr "Привет"
224230
225231#: Hud/HudParametrizedActionsPage.qml:132
226232msgid "Confirm"
227−msgstr "Подвердить"
233+msgstr "Подтвердить"
228234
229235#: Hud/Hud.qml:61 Hud/Hud.qml:99 Hud/Hud.qml:372
230236msgid "Type or say a command"
po/sl.po+32−27
@@ -8,7 +8,7 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-08-27 13:36-0400\n"
11−"PO-Revision-Date: 2013-07-02 12:59+0000\n"
11+"PO-Revision-Date: 2013-09-28 09:53+0000\n"
1212"Last-Translator: Damir Jerovšek <Unknown>\n"
1313"Language-Team: Slovenian <sl@li.org>\n"
1414"MIME-Version: 1.0\n"
@@ -16,8 +16,8 @@ msgstr ""
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || "
1818"n%100==4 ? 3 : 0);\n"
19−"X-Launchpad-Export-Date: 2013-08-30 05:37+0000\n"
20−"X-Generator: Launchpad (build 16750)\n"
19+"X-Launchpad-Export-Date: 2013-09-29 06:18+0000\n"
20+"X-Generator: Launchpad (build 16774)\n"
2121
2222#: Applications/applications.js:23
2323msgid "Phone"
@@ -25,7 +25,7 @@ msgstr "Telefon"
2525
2626#: Applications/applications.js:29
2727msgid "Camera"
28−msgstr ""
28+msgstr "Fotoaparat"
2929
3030#: Applications/applications.js:35
3131msgid "Gallery"
@@ -89,47 +89,50 @@ msgstr "YouTube"
8989
9090#: Components/EdgeDemoOverlay.qml:145
9191msgid "Skip intro"
92−msgstr ""
92+msgstr "Preskoči uvod"
9393
9494#: Components/EdgeDemo.qml:98
9595msgid "Right edge"
96−msgstr ""
96+msgstr "Desni rob"
9797
9898#: Components/EdgeDemo.qml:99
9999msgid "Try swiping from the right edge to unlock the phone"
100−msgstr ""
100+msgstr "Poskusite povleči od desnega roba za odklep telefona"
101101
102102#: Components/EdgeDemo.qml:135
103103msgid "Top edge"
104−msgstr ""
104+msgstr "Zgornji rob"
105105
106106#: Components/EdgeDemo.qml:136
107107msgid "Try swiping from the top edge to access the indicators"
108−msgstr ""
108+msgstr "Poskusite povleči od zgornjega roba za dostop do kazalnikov"
109109
110110#: Components/EdgeDemo.qml:161
111111msgid "Close"
112−msgstr ""
112+msgstr "Zapri"
113113
114114#: Components/EdgeDemo.qml:162
115115msgid "Swipe up again to close the settings screen"
116−msgstr ""
116+msgstr "Povlecite ponovno navzgor za zaprtje zaslona z nastavitvami"
117117
118118#: Components/EdgeDemo.qml:189
119119msgid "Left edge"
120−msgstr ""
120+msgstr "Levi rob"
121121
122122#: Components/EdgeDemo.qml:190
123123msgid "Swipe from the left to reveal the launcher for quick access to apps"
124124msgstr ""
125+"Poskusite povleči od leve za razkritje zaganjalnika za hiter dostop do "
126+"programov"
125127
126128#: Components/EdgeDemo.qml:217
127129msgid "Well done"
128−msgstr ""
130+msgstr "Odlično"
129131
130132#: Components/EdgeDemo.qml:218
131133msgid "You have now mastered the edge gestures and can start using the phone"
132134msgstr ""
135+"Zdaj, ko ste osvojili kretnje z robovi, lahko začnete uporabljati telefon"
133136
134137#: Components/PageHeader.qml:298
135138msgid "Recent searches"
@@ -139,35 +142,37 @@ msgstr "Nedavna iskanja"
139142#: Dash/Apps/AppInfo.qml:73
140143#, qt-format
141144msgid "(%1)"
142−msgstr ""
145+msgstr "(%1)"
143146
144147#. TRANSLATORS: Number of persons who wrote reviews for this app
145148#: Dash/Apps/AppInfo.qml:85
146149#, qt-format
147150msgid "%1 review"
148151msgid_plural "%1 reviews"
149−msgstr[0] ""
150−msgstr[1] ""
152+msgstr[0] "%1 ocen"
153+msgstr[1] "%1 ocena"
154+msgstr[2] "%1 oceni"
155+msgstr[3] "%1 ocene"
151156
152157#: Dash/Apps/AppPreview.qml:175
153158msgid "Rate this"
154−msgstr ""
159+msgstr "Ocenite"
155160
156161#: Dash/Apps/AppReviews.qml:72
157162msgid "Add a review"
158−msgstr ""
163+msgstr "Dodaj oceno"
159164
160165#: Dash/Apps/AppReviews.qml:84
161166msgid "Review"
162−msgstr ""
167+msgstr "Ocena"
163168
164169#: Dash/Apps/AppReviews.qml:118
165170msgid "Send"
166−msgstr ""
171+msgstr "Pošlji"
167172
168173#: Dash/Apps/AppReviews.qml:136
169174msgid "Comments:"
170−msgstr ""
175+msgstr "Opombe:"
171176
172177#: Dash/DashMusic.qml:27 Dash/DashVideos.qml:28
173178msgid "Featured"
@@ -199,19 +204,19 @@ msgstr "Videi"
199204
200205#: Dash/Video/VideoPreview.qml:130
201206msgid "Directed by:"
202−msgstr ""
207+msgstr "Režija:"
203208
204209#: Dash/Video/VideoPreview.qml:153
205210msgid "Starring:"
206−msgstr ""
211+msgstr "Igrajo:"
207212
208213#: Dash/Video/VideoPreview.qml:176
209214msgid "Author:"
210−msgstr ""
215+msgstr "Avtor:"
211216
212217#: Greeter/Lockscreen.qml:134
213218msgid "Emergency Call"
214−msgstr ""
219+msgstr "Klic v sili"
215220
216221#: Greeter/PassphraseLockscreen.qml:59
217222#, qt-format
@@ -220,7 +225,7 @@ msgstr "Pozdravljeni, %1"
220225
221226#: Greeter/PassphraseLockscreen.qml:59
222227msgid "Hello"
223−msgstr ""
228+msgstr "Pozdravljeni"
224229
225230#: Hud/HudParametrizedActionsPage.qml:132
226231msgid "Confirm"
@@ -253,4 +258,4 @@ msgstr "Nič se ne ujema z vašim iskalnim nizom."
253258#: Shell.qml:429
254259#, qt-format
255260msgid "Please enter %1"
256−msgstr ""
261+msgstr "Vnesite %1"
po/uk.po+26−21
@@ -8,16 +8,16 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2013-08-27 13:36-0400\n"
11−"PO-Revision-Date: 2013-07-21 05:47+0000\n"
12−"Last-Translator: Ярослав Смук <Smuk.Slavko@yandex.ua>\n"
11+"PO-Revision-Date: 2013-09-28 07:54+0000\n"
12+"Last-Translator: Yuri Chornoivan <yurchor@gmail.com>\n"
1313"Language-Team: Ukrainian <uk@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
1818"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2013-08-30 05:37+0000\n"
20−"X-Generator: Launchpad (build 16750)\n"
19+"X-Launchpad-Export-Date: 2013-09-29 06:18+0000\n"
20+"X-Generator: Launchpad (build 16774)\n"
2121
2222#: Applications/applications.js:23
2323msgid "Phone"
@@ -89,47 +89,51 @@ msgstr "YouTube"
8989
9090#: Components/EdgeDemoOverlay.qml:145
9191msgid "Skip intro"
92−msgstr ""
92+msgstr "Пропустити вступ"
9393
9494#: Components/EdgeDemo.qml:98
9595msgid "Right edge"
96−msgstr ""
96+msgstr "Правий край"
9797
9898#: Components/EdgeDemo.qml:99
9999msgid "Try swiping from the right edge to unlock the phone"
100−msgstr ""
100+msgstr "Спробуйте провести пальцем від правою краю, щоб розблокувати телефон"
101101
102102#: Components/EdgeDemo.qml:135
103103msgid "Top edge"
104−msgstr ""
104+msgstr "Верхній край"
105105
106106#: Components/EdgeDemo.qml:136
107107msgid "Try swiping from the top edge to access the indicators"
108108msgstr ""
109+"Спробуйте провести пальцем від верхнього краю, щоб розблокувати телефон"
109110
110111#: Components/EdgeDemo.qml:161
111112msgid "Close"
112−msgstr ""
113+msgstr "Закрити"
113114
114115#: Components/EdgeDemo.qml:162
115116msgid "Swipe up again to close the settings screen"
116−msgstr ""
117+msgstr "Проведіть пальцем ще раз, щоб закрити вікно параметрів"
117118
118119#: Components/EdgeDemo.qml:189
119120msgid "Left edge"
120−msgstr ""
121+msgstr "Лівий край"
121122
122123#: Components/EdgeDemo.qml:190
123124msgid "Swipe from the left to reveal the launcher for quick access to apps"
124125msgstr ""
126+"Проведіть пальцем від лівого краю, щоб відкрити панель запуску для "
127+"пришвидшення доступу до програм"
125128
126129#: Components/EdgeDemo.qml:217
127130msgid "Well done"
128−msgstr ""
131+msgstr "Добре"
129132
130133#: Components/EdgeDemo.qml:218
131134msgid "You have now mastered the edge gestures and can start using the phone"
132135msgstr ""
136+"Вами налаштовано жести від країв, ви можете почати користуватися телефоном"
133137
134138#: Components/PageHeader.qml:298
135139msgid "Recent searches"
@@ -139,35 +143,36 @@ msgstr "Нещодавні пошуки"
139143#: Dash/Apps/AppInfo.qml:73
140144#, qt-format
141145msgid "(%1)"
142−msgstr ""
146+msgstr "(%1)"
143147
144148#. TRANSLATORS: Number of persons who wrote reviews for this app
145149#: Dash/Apps/AppInfo.qml:85
146150#, qt-format
147151msgid "%1 review"
148152msgid_plural "%1 reviews"
149−msgstr[0] ""
150−msgstr[1] ""
153+msgstr[0] "%1 рецензія"
154+msgstr[1] "%1 рецензії"
155+msgstr[2] "%1 рецензій"
151156
152157#: Dash/Apps/AppPreview.qml:175
153158msgid "Rate this"
154−msgstr ""
159+msgstr "Оцінити"
155160
156161#: Dash/Apps/AppReviews.qml:72
157162msgid "Add a review"
158−msgstr ""
163+msgstr "Додати рецензію"
159164
160165#: Dash/Apps/AppReviews.qml:84
161166msgid "Review"
162−msgstr ""
167+msgstr "Рецензія"
163168
164169#: Dash/Apps/AppReviews.qml:118
165170msgid "Send"
166−msgstr ""
171+msgstr "Надіслати"
167172
168173#: Dash/Apps/AppReviews.qml:136
169174msgid "Comments:"
170−msgstr ""
175+msgstr "Коментарі:"
171176
172177#: Dash/DashMusic.qml:27 Dash/DashVideos.qml:28
173178msgid "Featured"
@@ -211,7 +216,7 @@ msgstr "Автор:"
211216
212217#: Greeter/Lockscreen.qml:134
213218msgid "Emergency Call"
214−msgstr ""
219+msgstr "Терміновий виклик"
215220
216221#: Greeter/PassphraseLockscreen.qml:59
217222#, qt-format
po/xh.ponew file+255
@@ -0,0 +1,255 @@
1+# Xhosa translation for unity8
2+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
3+# This file is distributed under the same license as the unity8 package.
4+# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
5+#
6+msgid ""
7+msgstr ""
8+"Project-Id-Version: unity8\n"
9+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10+"POT-Creation-Date: 2013-08-27 13:36-0400\n"
11+"PO-Revision-Date: 2013-09-28 13:20+0000\n"
12+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13+"Language-Team: Xhosa <xh@li.org>\n"
14+"MIME-Version: 1.0\n"
15+"Content-Type: text/plain; charset=UTF-8\n"
16+"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
18+"X-Launchpad-Export-Date: 2013-09-29 06:18+0000\n"
19+"X-Generator: Launchpad (build 16774)\n"
20+
21+#: Applications/applications.js:23
22+msgid "Phone"
23+msgstr ""
24+
25+#: Applications/applications.js:29
26+msgid "Camera"
27+msgstr ""
28+
29+#: Applications/applications.js:35
30+msgid "Gallery"
31+msgstr ""
32+
33+#: Applications/applications.js:40
34+msgid "Facebook"
35+msgstr ""
36+
37+#: Applications/applications.js:46
38+msgid "Browser"
39+msgstr ""
40+
41+#: Applications/applications.js:51
42+msgid "Twitter"
43+msgstr ""
44+
45+#: Applications/applications.js:57
46+msgid "GMail"
47+msgstr ""
48+
49+#: Applications/applications.js:62
50+msgid "Weather"
51+msgstr ""
52+
53+#: Applications/applications.js:68
54+msgid "Notepad"
55+msgstr ""
56+
57+#: Applications/applications.js:74
58+msgid "Calendar"
59+msgstr ""
60+
61+#: Applications/applications.js:80
62+msgid "Media Player"
63+msgstr ""
64+
65+#: Applications/applications.js:86
66+msgid "Evernote"
67+msgstr ""
68+
69+#: Applications/applications.js:91
70+msgid "Map"
71+msgstr ""
72+
73+#: Applications/applications.js:96
74+msgid "Pinterest"
75+msgstr ""
76+
77+#: Applications/applications.js:101
78+msgid "SoundCloud"
79+msgstr ""
80+
81+#: Applications/applications.js:106
82+msgid "Wikipedia"
83+msgstr ""
84+
85+#: Applications/applications.js:111
86+msgid "YouTube"
87+msgstr ""
88+
89+#: Components/EdgeDemoOverlay.qml:145
90+msgid "Skip intro"
91+msgstr ""
92+
93+#: Components/EdgeDemo.qml:98
94+msgid "Right edge"
95+msgstr ""
96+
97+#: Components/EdgeDemo.qml:99
98+msgid "Try swiping from the right edge to unlock the phone"
99+msgstr ""
100+
101+#: Components/EdgeDemo.qml:135
102+msgid "Top edge"
103+msgstr ""
104+
105+#: Components/EdgeDemo.qml:136
106+msgid "Try swiping from the top edge to access the indicators"
107+msgstr ""
108+
109+#: Components/EdgeDemo.qml:161
110+msgid "Close"
111+msgstr ""
112+
113+#: Components/EdgeDemo.qml:162
114+msgid "Swipe up again to close the settings screen"
115+msgstr ""
116+
117+#: Components/EdgeDemo.qml:189
118+msgid "Left edge"
119+msgstr ""
120+
121+#: Components/EdgeDemo.qml:190
122+msgid "Swipe from the left to reveal the launcher for quick access to apps"
123+msgstr ""
124+
125+#: Components/EdgeDemo.qml:217
126+msgid "Well done"
127+msgstr ""
128+
129+#: Components/EdgeDemo.qml:218
130+msgid "You have now mastered the edge gestures and can start using the phone"
131+msgstr ""
132+
133+#: Components/PageHeader.qml:298
134+msgid "Recent searches"
135+msgstr ""
136+
137+#. TRANSLATORS: Number of persons who rated this app
138+#: Dash/Apps/AppInfo.qml:73
139+#, qt-format
140+msgid "(%1)"
141+msgstr ""
142+
143+#. TRANSLATORS: Number of persons who wrote reviews for this app
144+#: Dash/Apps/AppInfo.qml:85
145+#, qt-format
146+msgid "%1 review"
147+msgid_plural "%1 reviews"
148+msgstr[0] ""
149+msgstr[1] ""
150+
151+#: Dash/Apps/AppPreview.qml:175
152+msgid "Rate this"
153+msgstr ""
154+
155+#: Dash/Apps/AppReviews.qml:72
156+msgid "Add a review"
157+msgstr ""
158+
159+#: Dash/Apps/AppReviews.qml:84
160+msgid "Review"
161+msgstr ""
162+
163+#: Dash/Apps/AppReviews.qml:118
164+msgid "Send"
165+msgstr ""
166+
167+#: Dash/Apps/AppReviews.qml:136
168+msgid "Comments:"
169+msgstr ""
170+
171+#: Dash/DashMusic.qml:27 Dash/DashVideos.qml:28
172+msgid "Featured"
173+msgstr ""
174+
175+#: Dash/DashMusic.qml:28 Dash/DashVideos.qml:29
176+msgid "Recent"
177+msgstr ""
178+
179+#: Dash/DashMusic.qml:29 Dash/DashVideos.qml:30
180+msgid "New Releases"
181+msgstr ""
182+
183+#: Dash/DashMusic.qml:30
184+msgid "Top Charting"
185+msgstr ""
186+
187+#: Dash/DashMusic.qml:91
188+msgid "Music"
189+msgstr ""
190+
191+#: Dash/DashVideos.qml:31
192+msgid "Popular Online"
193+msgstr ""
194+
195+#: Dash/DashVideos.qml:146
196+msgid "Videos"
197+msgstr ""
198+
199+#: Dash/Video/VideoPreview.qml:130
200+msgid "Directed by:"
201+msgstr ""
202+
203+#: Dash/Video/VideoPreview.qml:153
204+msgid "Starring:"
205+msgstr ""
206+
207+#: Dash/Video/VideoPreview.qml:176
208+msgid "Author:"
209+msgstr ""
210+
211+#: Greeter/Lockscreen.qml:134
212+msgid "Emergency Call"
213+msgstr ""
214+
215+#: Greeter/PassphraseLockscreen.qml:59
216+#, qt-format
217+msgid "Hello %1"
218+msgstr ""
219+
220+#: Greeter/PassphraseLockscreen.qml:59
221+msgid "Hello"
222+msgstr ""
223+
224+#: Hud/HudParametrizedActionsPage.qml:132
225+msgid "Confirm"
226+msgstr ""
227+
228+#: Hud/Hud.qml:61 Hud/Hud.qml:99 Hud/Hud.qml:372
229+msgid "Type or say a command"
230+msgstr ""
231+
232+#: Hud/Hud.qml:84
233+msgid "Loading. Please Wait..."
234+msgstr ""
235+
236+#: Hud/Hud.qml:89
237+msgid "Speak Now..."
238+msgstr ""
239+
240+#: Hud/Hud.qml:94
241+msgid "Speaking..."
242+msgstr ""
243+
244+#: Panel/SearchIndicator.qml:27
245+msgid "Search"
246+msgstr ""
247+
248+#: plugins/Unity/scope.cpp:317
249+msgid "Sorry, there is nothing that matches your search."
250+msgstr ""
251+
252+#: Shell.qml:429
253+#, qt-format
254+msgid "Please enter %1"
255+msgstr ""
src/Panel/Indicators/CMakeLists.txt−1
@@ -1,2 +1 @@
11add_subdirectory(client)
2−add_subdirectory(servicefiles)
src/Panel/Indicators/servicefiles/CMakeLists.txtdeleted−14
@@ -1,14 +0,0 @@
1−file(GLOB INDICATOR_SERVICE_FILES
2− ${CMAKE_CURRENT_SOURCE_DIR}/com.canonical.indicator.messages
3−)
4−
5−# copy indicators files into build directory for shadow builds
6−add_custom_target(IndicatorsServiceFiles ALL
7− COMMAND mkdir -p ${CMAKE_BINARY_DIR}/share/unity/indicators
8− COMMAND cp ${INDICATOR_SERVICE_FILES} ${CMAKE_BINARY_DIR}/share/unity/indicators
9− DEPENDS ${INDICATOR_SERVICE_FILES}
10−)
11−
12−install(FILES ${INDICATOR_SERVICE_FILES}
13− DESTINATION ${SHELL_APP_DIR}/unity/indicators
14−)
src/Panel/Indicators/servicefiles/com.canonical.indicator.messagesdeleted−10
@@ -1,10 +0,0 @@
1−[Indicator Service]
2−Name=indicator-messages
3−ObjectPath=/com/canonical/indicator/messages
4−Position=50
5−
6−[phone]
7−ObjectPath=/com/canonical/indicator/messages/phone
8−
9−[desktop]
10−ObjectPath=/com/canonical/indicator/messages/menu
tests/autopilot/unity8/application_lifecycle/__init__.pynew file+20
@@ -0,0 +1,20 @@
1+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2+#
3+# Unity Autopilot Test Suite
4+# Copyright (C) 2013 Canonical
5+#
6+# This program is free software: you can redistribute it and/or modify
7+# it under the terms of the GNU General Public License as published by
8+# the Free Software Foundation, either version 3 of the License, or
9+# (at your option) any later version.
10+#
11+# This program is distributed in the hope that it will be useful,
12+# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+# GNU General Public License for more details.
15+#
16+# You should have received a copy of the GNU General Public License
17+# along with this program. If not, see <http://www.gnu.org/licenses/>.
18+#
19+
20+"""Tests for the application lifecycle base package."""
tests/autopilot/unity8/application_lifecycle/tests/__init__.pynew file

No changes to the content.

tests/autopilot/unity8/application_lifecycle/tests/test_application_lifecycle.pynew file+136
@@ -0,0 +1,136 @@
1+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2+#
3+# Unity Autopilot Test Suite
4+# Copyright (C) 2013 Canonical
5+#
6+# This program is free software: you can redistribute it and/or modify
7+# it under the terms of the GNU General Public License as published by
8+# the Free Software Foundation, either version 3 of the License, or
9+# (at your option) any later version.
10+#
11+# This program is distributed in the hope that it will be useful,
12+# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+# GNU General Public License for more details.
15+#
16+# You should have received a copy of the GNU General Public License
17+# along with this program. If not, see <http://www.gnu.org/licenses/>.
18+#
19+
20+"""Tests for the application lifecycle."""
21+
22+from __future__ import absolute_import
23+
24+from unity8.shell import disable_qml_mocking
25+from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
26+
27+from autopilot.matchers import Eventually
28+from autopilot.platform import model
29+from testtools.matchers import Equals, NotEquals
30+
31+import logging
32+
33+logger = logging.getLogger(__name__)
34+
35+
36+class ApplicationLifecycleTests(UnityTestCase):
37+
38+ scenarios = _get_device_emulation_scenarios()
39+
40+ def setUp(self):
41+ super(ApplicationLifecycleTests, self).setUp()
42+ if model() == "Desktop":
43+ self.skipTest("Test cannot be run on the desktop.")
44+
45+ def swipe_screen_from_right(self):
46+ qml_view = self.main_window.get_qml_view()
47+ width = qml_view.width
48+ height = qml_view.height
49+ start_x = width
50+ start_y = int(height/2)
51+ end_x = int(width/2)
52+ end_y = start_y
53+
54+ logger.info("Swiping screen from the right edge")
55+ self.touch.drag(start_x, start_y, end_x, end_y)
56+
57+ def _get_current_focused_app_id(self):
58+ return self._proxy.select_single("Shell").currentFocusedAppId
59+
60+ def _launch_app(self, app_name):
61+ """Launches the application *app_name*
62+
63+ Assumes that the desktop file resides at:
64+ /usr/share/applications/{app_name}.desktop
65+
66+ """
67+ desktop_file = "--desktop_file_hint="\
68+ "/usr/share/applications/{app_name}.desktop".format(
69+ app_name=app_name
70+ )
71+ return self.launch_test_application(
72+ app_name,
73+ desktop_file,
74+ "--stage_hint=main_stage",
75+ app_type='qt'
76+ )
77+
78+ @disable_qml_mocking
79+ def test_can_launch_application(self):
80+ """Must be able to launch an application."""
81+ self.launch_unity()
82+ self.main_window.get_greeter().swipe()
83+
84+ app = self._launch_app("messaging-app")
85+
86+ self.assertThat(app, NotEquals(None))
87+ self.assertThat(
88+ self._get_current_focused_app_id(),
89+ Eventually(Equals("messaging-app"))
90+ )
91+
92+ @disable_qml_mocking
93+ def test_can_launch_multiple_applications(self):
94+ """A second application launched must be focused."""
95+ self.launch_unity()
96+ self.main_window.get_greeter().swipe()
97+
98+ self._launch_app("messaging-app")
99+ self.assertThat(
100+ self._get_current_focused_app_id(),
101+ Eventually(Equals("messaging-app"))
102+ )
103+
104+ self._launch_app("address-book-app")
105+ self.assertThat(
106+ self._get_current_focused_app_id(),
107+ Eventually(Equals("address-book-app"))
108+ )
109+
110+ @disable_qml_mocking
111+ def test_app_moves_from_unfocused_to_focused(self):
112+ """An application that is in the unfocused state must be able to be
113+ brought back to the focused state.
114+
115+ """
116+ self.launch_unity()
117+ self.main_window.get_greeter().swipe()
118+
119+ self._launch_app("messaging-app")
120+ self.assertThat(
121+ self._get_current_focused_app_id(),
122+ Eventually(Equals("messaging-app"))
123+ )
124+
125+ self._launch_app("address-book-app")
126+ self.assertThat(
127+ self._get_current_focused_app_id(),
128+ Eventually(Equals("address-book-app"))
129+ )
130+
131+ self.swipe_screen_from_right()
132+
133+ self.assertThat(
134+ self._get_current_focused_app_id(),
135+ Eventually(Equals("messaging-app"))
136+ )
tests/autopilot/unity8/shell/__init__.py+10
@@ -36,3 +36,13 @@ def with_lightdm_mock(mock_type):
3636 return fn(*args, **kwargs)
3737 return wrapper
3838 return with_lightdm_mock_internal
39+
40+
41+def disable_qml_mocking(fn):
42+ """Simple decorator that disables the QML mocks from being loaded."""
43+ @wraps(fn)
44+ def wrapper(*args, **kwargs):
45+ tests_self = args[0]
46+ tests_self._qml_mock_enabled = False
47+ return fn(*args, **kwargs)
48+ return wrapper
tests/autopilot/unity8/shell/tests/__init__.py+4−1
@@ -86,6 +86,7 @@ class UnityTestCase(AutopilotTestCase):
8686
8787 self._proxy = None
8888 self._lightdm_mock_type = None
89+ self._qml_mock_enabled = True
8990 self.touch = Touch.create()
9091 self._setup_display_details()
9192
@@ -160,7 +161,9 @@ class UnityTestCase(AutopilotTestCase):
160161
161162 if self._lightdm_mock_type is None:
162163 self.patch_lightdm_mock()
163− self._setup_extra_mock_environment_patch()
164+
165+ if self._qml_mock_enabled:
166+ self._setup_extra_mock_environment_patch()
164167
165168 app_proxy = self.launch_test_application(
166169 binary_path,
tests/mocks/AccountsService/AccountsService.cpp+3−3
@@ -24,7 +24,7 @@ AccountsService::AccountsService(QObject* parent)
2424{
2525}
2626
27−QString AccountsService::getUser()
27+QString AccountsService::user() const
2828{
2929 return "testuser";
3030}
@@ -34,7 +34,7 @@ void AccountsService::setUser(const QString &user)
3434 Q_UNUSED(user)
3535}
3636
37−bool AccountsService::getDemoEdges()
37+bool AccountsService::demoEdges() const
3838{
3939 return false;
4040}
@@ -44,7 +44,7 @@ void AccountsService::setDemoEdges(bool demoEdges)
4444 Q_UNUSED(demoEdges)
4545}
4646
47−QString AccountsService::getBackgroundFile()
47+QString AccountsService::backgroundFile() const
4848{
4949 return m_backgroundFile;
5050}
tests/mocks/AccountsService/AccountsService.h+6−6
@@ -28,26 +28,26 @@ class AccountsService: public QObject
2828{
2929 Q_OBJECT
3030 Q_PROPERTY (QString user
31− READ getUser
31+ READ user
3232 WRITE setUser
3333 NOTIFY userChanged)
3434 Q_PROPERTY (bool demoEdges
35− READ getDemoEdges
35+ READ demoEdges
3636 WRITE setDemoEdges
3737 NOTIFY demoEdgesChanged)
3838 Q_PROPERTY (QString backgroundFile
39− READ getBackgroundFile
39+ READ backgroundFile
4040 WRITE setBackgroundFile // only available in mock
4141 NOTIFY backgroundFileChanged)
4242
4343public:
4444 explicit AccountsService(QObject *parent = 0);
4545
46− QString getUser();
46+ QString user() const;
4747 void setUser(const QString &user);
48− bool getDemoEdges();
48+ bool demoEdges() const;
4949 void setDemoEdges(bool demoEdges);
50− QString getBackgroundFile();
50+ QString backgroundFile() const;
5151 void setBackgroundFile(const QString &backgroundFile);
5252
5353Q_SIGNALS:
tests/mocks/Ubuntu/DownloadDaemonListener/MockDownloadTracker.cpp+5
@@ -63,5 +63,10 @@ void MockDownloadTracker::startService()
6363 if(!m_service.isEmpty() && !m_dbusPath.isEmpty()) {
6464 m_active = true;
6565 Q_EMIT serviceReadyChanged(m_active);
66+ if(m_dbusPath == "finish") {
67+ Q_EMIT finished("downloadComplete");
68+ }else if(m_dbusPath == "error") {
69+ Q_EMIT error("DOWNLOAD ERROR");
70+ }
6671 }
6772}
tests/mocks/Unity/fake_preview.cpp+2
@@ -63,4 +63,6 @@ QString Preview::imageSourceUri() const
6363
6464void Preview::execute(const QString& actionId, const QHash<QString, QVariant>& hints)
6565{
66+ Q_UNUSED(actionId);
67+ Q_UNUSED(hints);
6668}
tests/mocks/Unity/fake_scope.h+2
@@ -90,6 +90,8 @@ Q_SIGNALS:
9090 // signals triggered by activate(..) or preview(..) requests.
9191 void previewReady(Preview *preview);
9292 void activateApplication(const QString &desktop);
93+ void showDash();
94+ void hideDash();
9395
9496protected:
9597
tests/plugins/AccountsService/client.cpp+2−2
@@ -50,9 +50,9 @@ private Q_SLOTS:
5050 AccountsService session;
5151 session.setUser("testuser");
5252 session.setDemoEdges(true);
53− QCOMPARE(session.getDemoEdges(), true);
53+ QCOMPARE(session.demoEdges(), true);
5454 session.setDemoEdges(false);
55− QCOMPARE(session.getDemoEdges(), false);
55+ QCOMPARE(session.demoEdges(), false);
5656 }
5757};
5858
tests/plugins/ListViewWithPageHeader/CMakeLists.txt+6
@@ -32,5 +32,11 @@ qt5_use_modules(listviewwithpageheadertestsectionExec Test Core Qml)
3232target_link_libraries(listviewwithpageheadertestsectionExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
3333add_custom_target(testlistviewwithpageheadersection ${CMAKE_CURRENT_BINARY_DIR}/listviewwithpageheadertestsectionExec -o ${CMAKE_BINARY_DIR}/testlistviewwithpageheadersection.xml,xunitxml -o -,txt)
3434
35+add_executable(listviewwithpageheadertestsectionexternalmodelExec listviewwithpageheadertestsectionexternalmodel.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/ListViewWithPageHeader/listviewwithpageheader.cpp)
36+qt5_use_modules(listviewwithpageheadertestsectionexternalmodelExec Test Core Qml)
37+target_link_libraries(listviewwithpageheadertestsectionexternalmodelExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
38+add_custom_target(testlistviewwithpageheadersectionexternalmodel ${CMAKE_CURRENT_BINARY_DIR}/listviewwithpageheadertestsectionexternalmodelExec -o ${CMAKE_BINARY_DIR}/testlistviewwithpageheadersectionexternalmodel.xml,xunitxml -o -,txt)
39+
3540add_dependencies(qmluitests testlistviewwithpageheader)
3641add_dependencies(qmluitests testlistviewwithpageheadersection)
42+add_dependencies(qmluitests testlistviewwithpageheadersectionexternalmodel)
tests/plugins/ListViewWithPageHeader/listviewwithpageheadertest.cpp+161
@@ -1655,6 +1655,167 @@ private Q_SLOTS:
16551655 QCOMPARE(spy.count(), 0);
16561656 }
16571657
1658+ void testOvershootOnSameSize()
1659+ {
1660+ QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 6));
1661+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 0);
1662+ QCOMPARE(lvwph->m_minYExtent, 0.);
1663+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
1664+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1665+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1666+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1667+ QCOMPARE(lvwph->contentY(), 0.);
1668+
1669+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 100));
1670+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 392));
1671+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 2);
1672+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1673+ verifyItem(0, 50., 392., false);
1674+ verifyItem(1, 442., 100., false);
1675+
1676+ QCOMPARE(lvwph->contentHeight(), lvwph->height());
1677+
1678+ QTest::mousePress(view, Qt::LeftButton, Qt::NoModifier, QPoint(0, 0));
1679+ QTest::qWait(100);
1680+ QTest::mouseMove(view, QPoint(0, 5));
1681+ QTest::qWait(100);
1682+ QTest::mouseMove(view, QPoint(0, 10));
1683+ QTest::qWait(100);
1684+ QTest::mouseMove(view, QPoint(0, 15));
1685+ QTest::qWait(100);
1686+ QTest::mouseMove(view, QPoint(0, 20));
1687+ QTest::qWait(100);
1688+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 2);
1689+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1690+ verifyItem(0, 55., 392., false);
1691+ verifyItem(1, 447., 100., false);
1692+ QCOMPARE(lvwph->m_minYExtent, 0.);
1693+ QCOMPARE(lvwph->m_clipItem->y(), -5.);
1694+
1695+ QTest::mouseRelease(view, Qt::LeftButton, Qt::NoModifier, QPoint(0, 15));
1696+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 2);
1697+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1698+ verifyItem(0, 50., 392., false);
1699+ verifyItem(1, 442., 100., false);
1700+ }
1701+
1702+ void testMaximizeVisibleAreaMoveDownAndShowHeader()
1703+ {
1704+ model->setProperty(0, "size", 800);
1705+ verifyItem(0, 50., 800., false);
1706+
1707+ lvwph->maximizeVisibleArea(0);
1708+ QTRY_COMPARE(lvwph->contentY(), 50.);
1709+
1710+ changeContentY(10);
1711+ QTRY_COMPARE(lvwph->contentY(), 60.);
1712+
1713+ lvwph->showHeader();
1714+ QTRY_VERIFY(!lvwph->m_contentYAnimation->isRunning());
1715+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 2);
1716+ QCOMPARE(lvwph->m_minYExtent, 50.);
1717+ QCOMPARE(lvwph->m_clipItem->y(), 60.);
1718+ QCOMPARE(lvwph->m_clipItem->clip(), true);
1719+ QCOMPARE(lvwph->m_headerItem->y(), 10.);
1720+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1721+ QCOMPARE(lvwph->contentY(), 10.);
1722+ verifyItem(0, -60., 800., false);
1723+ }
1724+
1725+ void testMaximizeVisibleAreaMoveUpAndShowHeader()
1726+ {
1727+ model->setProperty(0, "size", 800);
1728+ verifyItem(0, 50., 800., false);
1729+
1730+ lvwph->maximizeVisibleArea(0);
1731+ QTRY_COMPARE(lvwph->contentY(), 50.);
1732+
1733+ changeContentY(-10);
1734+ QTRY_COMPARE(lvwph->contentY(), 40.);
1735+
1736+ lvwph->showHeader();
1737+ QTRY_VERIFY(!lvwph->m_contentYAnimation->isRunning());
1738+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 2);
1739+ QCOMPARE(lvwph->m_minYExtent, 40.);
1740+ QCOMPARE(lvwph->m_clipItem->y(), 50.);
1741+ QCOMPARE(lvwph->m_clipItem->clip(), true);
1742+ QTRY_COMPARE(lvwph->m_headerItem->y(), 0.);
1743+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1744+ QCOMPARE(lvwph->contentY(), 0.);
1745+ verifyItem(0, -40., 800., false);
1746+ }
1747+
1748+ void testMaximizeVisibleAreaMoveDownAndUpAndShowHeader()
1749+ {
1750+ model->setProperty(0, "size", 800);
1751+ verifyItem(0, 50., 800., false);
1752+
1753+ lvwph->maximizeVisibleArea(0);
1754+ QTRY_COMPARE(lvwph->contentY(), 50.);
1755+
1756+ changeContentY(-10);
1757+ QTRY_COMPARE(lvwph->contentY(), 40.);
1758+ changeContentY(10);
1759+ QTRY_COMPARE(lvwph->contentY(), 50.);
1760+
1761+ lvwph->showHeader();
1762+ QTRY_VERIFY(!lvwph->m_contentYAnimation->isRunning());
1763+
1764+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 2);
1765+ QCOMPARE(lvwph->m_minYExtent, 50.);
1766+ QCOMPARE(lvwph->m_clipItem->y(), 50.);
1767+ QCOMPARE(lvwph->m_clipItem->clip(), true);
1768+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1769+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1770+ QCOMPARE(lvwph->contentY(), 0.);
1771+ verifyItem(0, -50., 800., false);
1772+ }
1773+
1774+ void testMaximizeVisibleAreaMoveUpAndDownAndShowHeader()
1775+ {
1776+ model->setProperty(0, "size", 800);
1777+ verifyItem(0, 50., 800., false);
1778+
1779+ lvwph->maximizeVisibleArea(0);
1780+ QTRY_COMPARE(lvwph->contentY(), 50.);
1781+
1782+ changeContentY(10);
1783+ QTRY_COMPARE(lvwph->contentY(), 60.);
1784+ changeContentY(-10);
1785+ QTRY_COMPARE(lvwph->contentY(), 50.);
1786+
1787+ lvwph->showHeader();
1788+ QTRY_VERIFY(!lvwph->m_contentYAnimation->isRunning());
1789+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 2);
1790+ QCOMPARE(lvwph->m_minYExtent, 40.);
1791+ QCOMPARE(lvwph->m_clipItem->y(), 60.);
1792+ QCOMPARE(lvwph->m_clipItem->clip(), true);
1793+ QCOMPARE(lvwph->m_headerItem->y(), 10.);
1794+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1795+ QCOMPARE(lvwph->contentY(), 10.);
1796+ verifyItem(0, -50., 800., false);
1797+ }
1798+
1799+ void testMaximizeVisibleAreaAndShowHeader()
1800+ {
1801+ model->setProperty(0, "size", 800);
1802+ verifyItem(0, 50., 800., false);
1803+
1804+ lvwph->maximizeVisibleArea(0);
1805+ QTRY_COMPARE(lvwph->contentY(), 50.);
1806+
1807+ lvwph->showHeader();
1808+ QTRY_VERIFY(!lvwph->m_contentYAnimation->isRunning());
1809+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 2);
1810+ QCOMPARE(lvwph->m_minYExtent, 50.);
1811+ QCOMPARE(lvwph->m_clipItem->y(), 50.);
1812+ QCOMPARE(lvwph->m_clipItem->clip(), true);
1813+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1814+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1815+ QCOMPARE(lvwph->contentY(), 0.);
1816+ verifyItem(0, -50., 800., false);
1817+ }
1818+
16581819private:
16591820 QQuickView *view;
16601821 ListViewWithPageHeader *lvwph;
tests/plugins/ListViewWithPageHeader/listviewwithpageheadertestsectionexternalmodel.cppnew file+251
@@ -0,0 +1,251 @@
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 <QSignalSpy>
23+#include <QSortFilterProxyModel>
24+#include <QtTestGui>
25+#pragma GCC diagnostic push
26+#pragma GCC diagnostic ignored "-pedantic"
27+#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0)
28+#include <private/qquicklistmodel_p.h>
29+#else
30+#include <private/qqmllistmodel_p.h>
31+#endif
32+#include <private/qquickanimation_p.h>
33+#include <private/qquickitem_p.h>
34+#pragma GCC diagnostic pop
35+
36+class StringListModel : public QAbstractListModel
37+{
38+public:
39+ StringListModel()
40+ {
41+ list << "A" << "B" << "C" << "D" << "E" << "F" << "G" << "H";
42+ }
43+
44+ int rowCount(const QModelIndex &parent) const
45+ {
46+ if (parent.isValid())
47+ return 0;
48+ else
49+ return list.count();
50+ }
51+
52+ QVariant data(const QModelIndex &index, int role) const
53+ {
54+ if (role == Qt::SizeHintRole) return 50;
55+ else if (role == Qt::DisplayRole) return list[index.row()];
56+ return QVariant();
57+ }
58+
59+ QHash<int, QByteArray> roleNames() const
60+ {
61+ QHash<int, QByteArray> hash;
62+ hash.insert(Qt::DisplayRole, "type");
63+ hash.insert(Qt::SizeHintRole, "size");
64+ return hash;
65+ }
66+
67+ void moveLastToFirst()
68+ {
69+ const int last = list.count() - 1;
70+ beginMoveRows(QModelIndex(), last, last, QModelIndex(), 0);
71+ list.move(last, 0);
72+ endMoveRows();
73+ }
74+
75+ QStringList list;
76+};
77+
78+class ListViewWithPageHeaderTestSection : public QObject
79+{
80+ Q_OBJECT
81+
82+private:
83+ void verifyItem(int visibleIndex, qreal pos, qreal height, bool culled, const QString &sectionHeader, bool sectionHeaderCulled)
84+ {
85+ QTRY_VERIFY(visibleIndex < lvwph->m_visibleItems.count());
86+ QTRY_COMPARE(lvwph->m_visibleItems[visibleIndex]->y(), pos);
87+ QTRY_COMPARE(lvwph->m_visibleItems[visibleIndex]->height(), height);
88+ QCOMPARE(QQuickItemPrivate::get(lvwph->m_visibleItems[visibleIndex]->m_item)->culled, culled);
89+ QCOMPARE(section(lvwph->m_visibleItems[visibleIndex]->m_sectionItem), sectionHeader);
90+ if (!sectionHeader.isNull()) {
91+ QCOMPARE(QQuickItemPrivate::get(lvwph->m_visibleItems[visibleIndex]->m_sectionItem)->culled, sectionHeaderCulled);
92+ QCOMPARE(sectionDelegateIndex(lvwph->m_visibleItems[visibleIndex]->m_sectionItem), lvwph->m_firstVisibleIndex + visibleIndex);
93+ }
94+ }
95+
96+ void changeContentY(qreal change)
97+ {
98+ const qreal dest = lvwph->contentY() + change;
99+ if (dest > lvwph->contentY()) {
100+ const qreal jump = 25;
101+ while (lvwph->contentY() + jump < dest) {
102+ lvwph->setContentY(lvwph->contentY() + jump);
103+ QTest::qWait(1);
104+ }
105+ } else {
106+ const qreal jump = -25;
107+ while (lvwph->contentY() + jump > dest) {
108+ lvwph->setContentY(lvwph->contentY() + jump);
109+ QTest::qWait(1);
110+ }
111+ }
112+ lvwph->setContentY(dest);
113+ QTest::qWait(1);
114+ }
115+
116+ void scrollToTop()
117+ {
118+ const qreal jump = -25;
119+ while (!lvwph->isAtYBeginning()) {
120+ if (lvwph->contentY() + jump > -lvwph->minYExtent()) {
121+ lvwph->setContentY(lvwph->contentY() + jump);
122+ } else {
123+ lvwph->setContentY(lvwph->contentY() - 1);
124+ }
125+ QTest::qWait(1);
126+ }
127+ }
128+
129+ void scrollToBottom()
130+ {
131+ const qreal jump = 25;
132+ while (!lvwph->isAtYEnd()) {
133+ if (lvwph->contentY() + lvwph->height() + jump < lvwph->contentHeight()) {
134+ lvwph->setContentY(lvwph->contentY() + jump);
135+ } else {
136+ lvwph->setContentY(lvwph->contentY() + 1);
137+ }
138+ QTest::qWait(1);
139+ }
140+ }
141+
142+ void verifyInitialTopPosition()
143+ {
144+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 0);
145+ QCOMPARE(lvwph->m_firstVisibleIndex, -1);
146+ QCOMPARE(lvwph->m_minYExtent, 0.);
147+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
148+ QCOMPARE(lvwph->m_clipItem->clip(), false);
149+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
150+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
151+ QCOMPARE(lvwph->contentY(), 0.);
152+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
153+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
154+ }
155+
156+ QString section(QQuickItem *item)
157+ {
158+ return item ? QQmlEngine::contextForObject(item)->parentContext()->contextProperty(QLatin1String("section")).toString() : QString();
159+ }
160+
161+ int sectionDelegateIndex(QQuickItem *item)
162+ {
163+ return item ? QQmlEngine::contextForObject(item)->parentContext()->contextProperty(QLatin1String("delegateIndex")).toInt() : -1;
164+ }
165+
166+private Q_SLOTS:
167+
168+ void initTestCase()
169+ {
170+ }
171+
172+ void init()
173+ {
174+ view = new QQuickView();
175+ view->engine()->addImportPath(BUILT_PLUGINS_DIR);
176+ view->setSource(QUrl::fromLocalFile(LISTVIEWWITHPAGEHEADER_FOLDER "/test_sectionexternalmodel.qml"));
177+ lvwph = dynamic_cast<ListViewWithPageHeader*>(view->rootObject()->findChild<QQuickFlickable*>());
178+ QVERIFY(lvwph);
179+ view->show();
180+ QTest::qWaitForWindowExposed(view);
181+
182+ verifyInitialTopPosition();
183+ }
184+
185+ void cleanup()
186+ {
187+ delete view;
188+ }
189+
190+ void testCreationDeletion()
191+ {
192+ // Nothing, init/cleanup already tests this
193+ }
194+
195+ void testMoveWithProxy()
196+ {
197+ StringListModel m;
198+ QSortFilterProxyModel proxy;
199+ proxy.setSourceModel(&m);
200+
201+ lvwph->setModel(&proxy);
202+
203+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 8);
204+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
205+ verifyItem(0, 50., 90., false, "A", false);
206+ verifyItem(1, 140., 90., false, "B", false);
207+ verifyItem(2, 230., 90., false, "C", false);
208+ verifyItem(3, 320., 90., false, "D", false);
209+ verifyItem(4, 410., 90., false, "E", false);
210+ verifyItem(5, 500., 90., false, "F", false);
211+ verifyItem(6, 590., 90., true, "G", true);
212+ verifyItem(7, 680., 90., true, "H", true);
213+ QCOMPARE(lvwph->m_minYExtent, 0.);
214+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
215+ QCOMPARE(lvwph->m_clipItem->clip(), false);
216+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
217+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
218+ QCOMPARE(lvwph->contentY(), 0.);
219+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
220+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
221+
222+ m.moveLastToFirst();
223+
224+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 8);
225+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
226+ verifyItem(0, 50., 90., false, "H", false);
227+ verifyItem(1, 140., 90., false, "A", false);
228+ verifyItem(2, 230., 90., false, "B", false);
229+ verifyItem(3, 320., 90., false, "C", false);
230+ verifyItem(4, 410., 90., false, "D", false);
231+ verifyItem(5, 500., 90., false, "E", false);
232+ verifyItem(6, 590., 90., true, "F", true);
233+ verifyItem(7, 680., 90., true, "G", true);
234+ QCOMPARE(lvwph->m_minYExtent, 0.);
235+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
236+ QCOMPARE(lvwph->m_clipItem->clip(), false);
237+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
238+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
239+ QCOMPARE(lvwph->contentY(), 0.);
240+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
241+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
242+ }
243+
244+private:
245+ QQuickView *view;
246+ ListViewWithPageHeader *lvwph;
247+};
248+
249+QTEST_MAIN(ListViewWithPageHeaderTestSection)
250+
251+#include "listviewwithpageheadertestsectionexternalmodel.moc"
tests/plugins/ListViewWithPageHeader/test_sectionexternalmodel.qmlnew file+74
@@ -0,0 +1,74 @@
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+ ListViewWithPageHeader {
26+ id: listView
27+ width: parent.width
28+ anchors.top: parent.top
29+ anchors.bottom: parent.bottom
30+ model: model
31+ delegate: Rectangle {
32+ property bool timerDone: false
33+ width: parent.width - 20
34+ x: 10
35+ color: index % 2 == 0 ? "red" : "blue"
36+ height: timerDone ? size : 350
37+ Text {
38+ text: index
39+ }
40+ Timer {
41+ id: sizeTimer
42+ interval: 10;
43+ onTriggered: {
44+ timerDone = true
45+ }
46+ }
47+ Component.onCompleted: {
48+ sizeTimer.start()
49+ }
50+ }
51+
52+ pageHeader: Rectangle {
53+ color: "transparent"
54+ width: parent.width
55+ height: 50
56+ implicitHeight: 50
57+ Text {
58+ anchors.fill: parent
59+ text: "APPS"
60+ font.pixelSize: 40
61+ }
62+ }
63+
64+ sectionProperty: "type"
65+ sectionDelegate: Component {
66+ Rectangle {
67+ color: "green"
68+ height: 40
69+ Text { text: section; font.pixelSize: 34 }
70+ anchors { left: parent.left; right: parent.right }
71+ }
72+ }
73+ }
74+}
tests/plugins/Unity/Launcher/launchermodeltest.cpp+61−2
@@ -62,7 +62,14 @@ public:
6262 return QString();
6363 }
6464 unity::shell::application::ApplicationInfoInterface *get(int index) const { return m_list.at(index); }
65− unity::shell::application::ApplicationInfoInterface *findApplication(const QString &) const { return nullptr; }
65+ unity::shell::application::ApplicationInfoInterface *findApplication(const QString &appId) const {
66+ Q_FOREACH(MockApp* app, m_list) {
67+ if (app->appId() == appId) {
68+ return app;
69+ }
70+ }
71+ return nullptr;
72+ }
6673 unity::shell::application::ApplicationInfoInterface *startApplication(const QString &, const QStringList &) { return nullptr; }
6774 bool stopApplication(const QString &) { return false; }
6875 bool focusApplication(const QString &appId) {
@@ -151,9 +158,54 @@ private Q_SLOTS:
151158 QCOMPARE(launcherModel->get(1)->pinned(), false);
152159 }
153160
161+ void testRemove_data() {
162+
163+ QTest::addColumn<bool>("pinned");
164+ QTest::addColumn<bool>("running");
165+
166+ QTest::newRow("non-pinned, running") << false << true;
167+ QTest::newRow("pinned, running") << true << false;
168+ QTest::newRow("pinned, non-running") << true << false;
169+ }
170+
154171 void testRemove() {
172+ QFETCH(bool, pinned);
173+ QFETCH(bool, running);
174+
175+ // In the beginning we always have two items
155176 QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
156− launcherModel->requestRemove(launcherModel->get(0)->appId());
177+
178+ // pin one if required
179+ if (pinned) {
180+ launcherModel->pin(launcherModel->get(1)->appId());
181+ }
182+
183+ // stop it if required
184+ if (!running) {
185+ appManager->removeApplication(1);
186+ }
187+
188+ // Now remove it
189+ launcherModel->requestRemove(launcherModel->get(1)->appId());
190+
191+ if (running) {
192+ // both apps are running, both apps must still be here
193+ QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
194+
195+ // Item must be unpinned now
196+ QCOMPARE(launcherModel->get(1)->pinned(), false);
197+
198+ } else if (pinned) {
199+ // Item 1 must go away, item 0 is here to stay
200+ QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
201+ }
202+
203+ // done our checks. now stop the app if was still running
204+ if (running) {
205+ appManager->removeApplication(1);
206+ }
207+
208+ // It needs to go away in any case now
157209 QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
158210 }
159211
@@ -181,6 +233,13 @@ private Q_SLOTS:
181233
182234 // quicklist needs to transform to remove item. trigger it and check it item goes away
183235 launcherModel->quickListActionInvoked(launcherModel->get(0)->appId(), pinActionIndex);
236+ QCOMPARE(launcherModel->get(0)->pinned(), false);
237+
238+ // still needs to be here as the app is still here
239+ QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
240+ // close the app
241+ appManager->removeApplication(0);
242+ // Now it needs to go away
184243 QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
185244 }
186245
tests/plugins/Unity/previewbindingstest.cpp+27
@@ -19,6 +19,7 @@
1919
2020#include <UnityCore/Preview.h>
2121#include <UnityCore/GLibWrapper.h>
22+#include <UnityCore/Variant.h>
2223#include <unity-protocol.h>
2324
2425#include "genericpreview.h"
@@ -48,7 +49,23 @@ void PreviewBindingsTest::testGenericPreview()
4849 UNITY_PROTOCOL_LAYOUT_HINT_LEFT);
4950 unity::glib::Object<GObject> genPrv(rawPreview);
5051
52+ // create local result
53+ unity::glib::HintsMap hints;
54+ hints["a"] = unity::glib::Variant(g_variant_new_string("b"));
55+ unity::dash::LocalResult localResult;
56+ localResult.uri = "http://foo";
57+ localResult.icon_hint = "xyz";
58+ localResult.category_index = 1;
59+ localResult.result_type = 2;
60+ localResult.mimetype = "abc";
61+ localResult.name = "baz";
62+ localResult.comment = "qwerty";
63+ localResult.dnd_uri = "zzz";
64+ localResult.hints = hints;
65+
5166 auto corePrv = unity::dash::Preview::PreviewForProtocolObject(genPrv);
67+ corePrv->preview_result = localResult;
68+
5269 auto prv = Preview::newFromUnityPreview(corePrv);
5370
5471 QCOMPARE(prv != nullptr, true);
@@ -64,6 +81,16 @@ void PreviewBindingsTest::testGenericPreview()
6481 QCOMPARE(act->displayName(), QString("Action1"));
6582 QCOMPARE(act->iconHint(), QString("/foo.png"));
6683
84+ Result* res = prv->result().value<Result*>();
85+ QCOMPARE(res->uri(), QString("http://foo"));
86+ QCOMPARE(res->iconHint(), QString("xyz"));
87+ QCOMPARE(res->categoryIndex(), 1u);
88+ QCOMPARE(res->resultType(), 2u);
89+ QCOMPARE(res->mimeType(), QString("abc"));
90+ QCOMPARE(res->title(), QString("baz"));
91+ QCOMPARE(res->dndUri(), QString("zzz"));
92+ QCOMPARE(res->metadata().toHash()["a"].toString(), QString("b"));
93+
6794 g_object_unref(icon);
6895 g_object_unref(iconFile);
6996}
tests/plugins/Unity/resultstest.cpp+1
@@ -71,6 +71,7 @@ void ResultsTest::testIconColumn_data()
7171 QTest::newRow("absolute path") << "/usr/share/icons/example.png" << "/usr/share/icons/example.png";
7272 QTest::newRow("file uri") << "file:///usr/share/icons/example.png" << "file:///usr/share/icons/example.png";
7373 QTest::newRow("http uri") << "http://images.ubuntu.com/example.jpg" << "http://images.ubuntu.com/example.jpg";
74+ QTest::newRow("image uri") << "image://thumbnail/with/arguments?passed_to=ImageProvider" << "image://thumbnail/with/arguments?passed_to=ImageProvider";
7475 QTest::newRow("themed icon") << "accessories-other" << "image://theme/accessories-other";
7576 QTest::newRow("fileicon") << ". GFileIcon http://example.org/resource.gif" << "http://example.org/resource.gif";
7677 QTest::newRow("themedicon") << ". GThemedIcon accessories-other accessories generic" << "image://theme/accessories-other,accessories,generic";
tests/qmltests/CMakeLists.txt+1−1
@@ -13,7 +13,6 @@ set(qmltest_DEFAULT_NO_ADD_TEST FALSE)
1313set(qmltest_DEFAULT_PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=minimal")
1414add_qml_test(Components AnimationControllerWithSignals)
1515add_qml_test(Components Carousel)
16−add_qml_test(Components CrossFadeImage)
1716add_qml_test(Components MathLocal)
1817add_qml_test(Components OpenEffect)
1918add_qml_test(Components RatingStars)
@@ -32,6 +31,7 @@ add_manual_qml_test(Components DragHandle IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugi
3231add_qml_test(Components DraggingArea)
3332add_qml_test(Components EdgeDemoOverlay)
3433add_qml_test(Components FilterGrid IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins)
34+add_qml_test(Components LazyImage)
3535add_qml_test(Components ResponsiveFlowView)
3636add_qml_test(Components ResponsiveGridView)
3737add_qml_test(Components Revealer)
tests/qmltests/Components/tst_CrossFadeImage.qmldeleted−125
@@ -1,125 +0,0 @@
1−/*
2− * Copyright 2013 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import QtTest 1.0
19−import "../../../Components"
20−
21−TestCase {
22− name: "CrossFadeImage"
23−
24− property alias status: crossFadeImage.status
25− property alias source: crossFadeImage.source
26− property alias crossFade: crossFadeImage.crossFade
27− property alias fadeInFirst: crossFadeImage.fadeInFirst
28− property alias running: crossFadeImage.running
29−
30− CrossFadeImage {
31− id: crossFadeImage
32− }
33−
34− SignalSpy {
35− id: signalSpy
36− target: crossFadeImage
37− }
38−
39− function initTestFunction(argCrossFade, argFadeInFirst) {
40− source = ""
41− crossFade = argCrossFade
42− fadeInFirst = argFadeInFirst
43− compare(status, Image.Null, "Could not reset CrossFadeImage")
44− }
45−
46− function loadImage(url) {
47− console.log("Loading image...")
48− source = url
49−
50− signalSpy.signalName = "statusChanged"
51− signalSpy.wait()
52−
53− if (status == Image.Null) {
54− signalSpy.clear()
55− signalSpy.wait()
56− }
57−
58− if (status == Image.Loading) {
59− signalSpy.clear()
60− signalSpy.wait()
61− }
62−
63− compare(status, Image.Ready, "Image not ready")
64− console.log("Image loaded.")
65− }
66−
67− function waitForAnimation() {
68− signalSpy.signalName = "runningChanged"
69−
70− if (!running) {
71− signalSpy.clear()
72− signalSpy.wait()
73− compare(running, true, "Animation did not start")
74− }
75−
76− signalSpy.clear()
77− console.log("Waiting for animation to finish...")
78− signalSpy.wait()
79− compare(running, false, "Animation did not stop within 5 seconds.")
80− }
81−
82− function cleanupTest() {
83− compare(running, false, "Animation is running after testcase")
84− compare(crossFadeImage.__nextImage.source, "", "nextimage source is not reset")
85− }
86−
87− function test_fadeFirst() {
88− initTestFunction(true, true)
89−
90− loadImage("../../../graphics/phone_background.jpg")
91−
92− waitForAnimation()
93−
94− cleanupTest()
95− }
96−
97− function test_no_fadeFirst() {
98− initTestFunction(true, false)
99−
100− loadImage("../../../graphics/phone_background.jpg")
101−
102− cleanupTest()
103− }
104−
105− function test_crossFade() {
106− initTestFunction(true, false)
107−
108− loadImage("../../../graphics/phone_background.jpg")
109−
110− loadImage("../../../graphics/tablet_background.jpg")
111−
112− // Due to the internal implementation, __currentImage and __nextImage are swapped before the animation starts
113− // Make sure z order reflects that too.
114− compare(crossFadeImage.__currentImage.z > crossFadeImage.__nextImage.z, true, "new image should be above old image")
115− compare(crossFadeImage.__currentImage.opacity < 0.5, true)
116− compare(crossFadeImage.__nextImage.opacity > 0.5, true)
117−
118− waitForAnimation()
119−
120− compare(crossFadeImage.__currentImage.opacity > 0.5, true)
121− compare(crossFadeImage.__nextImage.opacity < 0.5, true)
122−
123− cleanupTest()
124− }
125−}
tests/qmltests/Components/tst_LazyImage.qmlnew file+156
@@ -0,0 +1,156 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import QtTest 1.0
19+import "../../../Components"
20+import Ubuntu.Components 0.1
21+import Unity.Test 0.1 as UT
22+import "tst_LazyImage"
23+
24+Rectangle {
25+ width: units.gu(120)
26+ height: units.gu(70)
27+
28+ Rectangle {
29+ id: baseRect
30+ anchors {
31+ fill: parent
32+ rightMargin: 2 * parent.width / 3
33+ }
34+
35+ color: "grey"
36+
37+ Column {
38+ anchors { fill: parent; margins: units.gu(5) }
39+
40+ Label {
41+ height: units.gu(4)
42+ text: "Unbound"
43+ color: "white"
44+ verticalAlignment: Text.AlignBottom
45+ }
46+
47+ LazyImage {
48+ id: lazy1
49+ }
50+
51+ Label {
52+ height: units.gu(4)
53+ text: "Width-bound"
54+ color: "white"
55+ verticalAlignment: Text.AlignBottom
56+ }
57+
58+ LazyImage {
59+ id: lazy2
60+ width: units.gu(30)
61+ scaleTo: "width"
62+ }
63+
64+ Label {
65+ height: units.gu(4)
66+ text: "Height-bound"
67+ color: "white"
68+ verticalAlignment: Text.AlignBottom
69+ }
70+
71+ LazyImage {
72+ id: lazy3
73+ height: units.gu(10)
74+ scaleTo: "height"
75+ }
76+ }
77+ }
78+
79+ Rectangle {
80+ id: controlsRect
81+ anchors {
82+ fill: parent
83+ leftMargin: parent.width / 3
84+ }
85+
86+ color: "lightgrey"
87+
88+ Column {
89+ id: controls
90+ spacing: units.gu(1)
91+
92+ anchors { fill: parent; margins: units.gu(3) }
93+
94+ ImageControls { id: controls1; image: lazy1 }
95+ ImageControls { id: controls2; image: lazy2 }
96+ ImageControls { id: controls3; image: lazy3 }
97+ }
98+ }
99+
100+ UT.UnityTestCase {
101+ name: "Stage"
102+ when: windowShown
103+
104+ function cleanup() {
105+ controls1.blank();
106+ tryCompare(lazy1, "width", units.gu(10));
107+ controls2.blank();
108+ tryCompare(lazy2, "height", units.gu(10));
109+ controls3.blank();
110+ tryCompare(lazy3, "width", units.gu(10));
111+ }
112+
113+ function test_lazyimage_data() {
114+ return [
115+ {tag: "Unbound Blank", image: lazy1, func: controls1.blank, width: units.gu(10), height: units.gu(10), placeholder: true},
116+ {tag: "Unbound Wide", image: lazy1, func: controls1.wide, transition: "readyTransition", width: 160, height: 80},
117+ {tag: "Unbound Square", image: lazy1, func: controls1.square, transition: "readyTransition", width: 160, height: 160},
118+ {tag: "Unbound Portrait", image: lazy1, func: controls1.portrait, transition: "readyTransition", width: 80, height: 160},
119+ {tag: "Unbound Bad path", image: lazy1, func: controls1.badpath, transition: "genericTransition", width: units.gu(10), height: units.gu(10), placeholder: true, error: true},
120+ {tag: "Width-bound Blank", image: lazy2, func: controls2.blank, width: units.gu(30), height: units.gu(10), placeholder: true},
121+ {tag: "Width-bound Wide", image: lazy2, func: controls2.wide, transition: "readyTransition", width: units.gu(30), height: units.gu(15)},
122+ {tag: "Width-bound Square", image: lazy2, func: controls2.square, transition: "readyTransition", width: units.gu(30), height: units.gu(30)},
123+ {tag: "Width-bound Portrait", image: lazy2, func: controls2.portrait, transition: "readyTransition", width: units.gu(30), height: units.gu(60)},
124+ {tag: "Width-bound Bad path", image: lazy2, func: controls2.badpath, transition: "genericTransition", width: units.gu(30), height: units.gu(10), placeholder: true, error: true},
125+ {tag: "Height-bound Blank", image: lazy3, func: controls3.blank, width: units.gu(10), height: units.gu(10), placeholder: true},
126+ {tag: "Height-bound Wide", image: lazy3, func: controls3.wide, transition: "readyTransition", width: units.gu(20), height: units.gu(10)},
127+ {tag: "Height-bound Square", image: lazy3, func: controls3.square, transition: "readyTransition", width: units.gu(10), height: units.gu(10)},
128+ {tag: "Height-bound Portrait", image: lazy3, func: controls3.portrait, transition: "readyTransition", width: units.gu(5), height: units.gu(10)},
129+ {tag: "Height-bound Bad path", image: lazy3, func: controls3.badpath, transition: "genericTransition", width: units.gu(10), height: units.gu(10), placeholder: true, error: true},
130+ ]
131+ }
132+
133+ function test_lazyimage(data) {
134+ data.func();
135+
136+ if (data.transition) {
137+ // wait for the transition to complete
138+ var transition = findInvisibleChild(data.image, data.transition);
139+ tryCompare(transition, "running", true);
140+ tryCompare(transition, "running", false);
141+ }
142+
143+ // check the dimensions
144+ compare(data.image.width, data.width);
145+ compare(data.image.height, data.height);
146+
147+ // check the placeholder
148+ var placeholder = findChild(data.image, "placeholder");
149+ compare(placeholder.visible, data.placeholder ? true : false);
150+
151+ // check the error image
152+ var error = findChild(data.image, "errorImage");
153+ compare(error.visible, data.error ? true : false);
154+ }
155+ }
156+}
tests/qmltests/Components/tst_LazyImage/ImageControls.qmlnew file+67
@@ -0,0 +1,67 @@
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 Ubuntu.Components 0.1
19+import "../../../../Components"
20+
21+Row {
22+ property LazyImage image
23+
24+ anchors { left: parent.left; right: parent.right }
25+ spacing: units.gu(1)
26+
27+ function blank() { blankButton.clicked() }
28+ function wide() { wideButton.clicked() }
29+ function square() { squareButton.clicked() }
30+ function portrait() { portraitButton.clicked() }
31+ function badpath() { badpathButton.clicked() }
32+
33+ Button {
34+ id: blankButton
35+ width: parent / 5
36+ text: "Blank"
37+ onClicked: image.source = ""
38+ }
39+
40+ Button {
41+ id: wideButton
42+ width: parent / 5
43+ text: "Wide"
44+ onClicked: image.source = "wide.png"
45+ }
46+
47+ Button {
48+ id: squareButton
49+ width: parent / 5
50+ text: "Square"
51+ onClicked: image.source = "square.png"
52+ }
53+
54+ Button {
55+ id: portraitButton
56+ width: parent / 5
57+ text: "Portrait"
58+ onClicked: image.source = "portrait.png"
59+ }
60+
61+ Button {
62+ id: badpathButton
63+ width: parent / 5
64+ text: "Bad path"
65+ onClicked: image.source = "bad/path"
66+ }
67+}
tests/qmltests/Components/tst_LazyImage/portrait.pngnew file

Binary file not shown.

tests/qmltests/Components/tst_LazyImage/square.pngnew file

Binary file not shown.

tests/qmltests/Components/tst_LazyImage/wide.pngnew file

Binary file not shown.

tests/qmltests/Dash/Apps/tst_AppPreview.qml+75−2
@@ -25,6 +25,9 @@ Item {
2525 width: units.gu(60)
2626 height: units.gu(80)
2727
28+ // Fake shell
29+ QtObject { id: shell; property int height: appPreview.height }
30+
2831 property var calls: []
2932
3033 SignalSpy {
@@ -45,6 +48,8 @@ Item {
4548 ["Unity User", 10, "10/02/2013", root.commentary],
4649 ]
4750 }
51+ QtObject { id: showProgress; property bool value: true }
52+ QtObject { id: progressSource; property string value: "service" }
4853
4954 QtObject {
5055 id: data
@@ -66,8 +71,30 @@ Item {
6671 ]
6772 }
6873
74+ QtObject {
75+ id: dataProgress
76+ property string title: "Unity App"
77+ property string appIcon: "fake_image.png"
78+ property string description: "This is an Application description"
79+ property real rating: rating.value
80+ property int numRatings: reviews.value
81+ property var execute: root.fake_call
82+ property var infoMap: {
83+ "show_progressbar": showProgress,
84+ "more-screenshots": screenshots,
85+ "rated": rated,
86+ "comments": comments,
87+ "progressbar_source": progressSource
88+ }
89+ property var actions: [
90+ { "id": 123, "displayName": "action1" },
91+ { "id": 456, "displayName": "action2" },
92+ { "id": 789, "displayName": "action3" },
93+ ]
94+ }
95+
6996 function fake_call(id, data){
70− root.calls[root.calls.length] = id;
97+ root.calls[root.calls.length] = [id, data];
7198 }
7299
73100 // The component under test
@@ -89,6 +116,10 @@ Item {
89116 reviewField.focus = false;
90117 reviewField.text = "";
91118 data.rating = rating.value;
119+ dataProgress.infoMap["progressbar_source"].value = "service";
120+ var appReviews = findChild(appPreview, "appReviews");
121+ appReviews.visible = false;
122+ appPreview.keyboardSize = 0;
92123 }
93124
94125 function test_actions() {
@@ -102,7 +133,7 @@ Item {
102133
103134 var actions = data.actions;
104135 for(var i = 0; i < actions.length; i++) {
105− compare(root.calls[i], actions[i].id, "Id of action not found.");
136+ compare(root.calls[i][0], actions[i].id, "Id of action not found.");
106137 }
107138 }
108139
@@ -124,6 +155,7 @@ Item {
124155
125156 function test_review_focus() {
126157 var appReviews = findChild(appPreview, "appReviews");
158+ appReviews.visible = true;
127159 var sendButton = findChild(appReviews, "sendButton");
128160 var reviewField = findChild(appReviews, "reviewField");
129161
@@ -162,5 +194,46 @@ Item {
162194 verify(buttons.visible == true);
163195 }
164196
197+ function test_progress_show() {
198+ appPreview.previewData = dataProgress;
199+ var progress = findChild(appPreview, "progressBar");
200+ verify(progress.visible == true);
201+ }
202+
203+ function test_progress_download_finish() {
204+ appPreview.previewData = dataProgress;
205+ var progress = findChild(appPreview, "progressBar");
206+ dataProgress.infoMap["progressbar_source"].value = "finish";
207+
208+ var actions = dataProgress.actions;
209+ compare(root.calls[0][0], actions[0].id, "Id of action not found.");
210+ compare(root.calls[0][1], {}, "Data of action not found.");
211+ }
212+
213+ function test_progress_download_error() {
214+ appPreview.previewData = dataProgress;
215+ var progress = findChild(appPreview, "progressBar");
216+ dataProgress.infoMap["progressbar_source"].value = "error";
217+
218+ var actions = dataProgress.actions;
219+ compare(root.calls[0][0], actions[1].id, "Id of action not found.");
220+ compare(root.calls[0][1], {"error": "DOWNLOAD ERROR"}, "Data of action not found.");
221+ }
222+
223+ function test_automatic_scroll_on_keyboard_shown() {
224+ waitForRendering(appPreview);
225+ var appReviews = findChild(appPreview, "appReviews");
226+ appReviews.visible = true;
227+
228+ var leftFlickable = findChild(appPreview, "leftFlickable");
229+ leftFlickable.contentY = leftFlickable.contentHeight;
230+ var reviewField = findChild(appReviews, "reviewField");
231+ appPreview.keyboardSize = 400;
232+ appReviews.editing(reviewField);
233+ var newFlickPos = leftFlickable.contentY;
234+ var keyboardY = shell.height - appPreview.keyboardSize;
235+ verify(newFlickPos < keyboardY);
236+ }
237+
165238 }
166239}
tests/qmltests/Dash/tst_DashContent.qml+1−1
@@ -106,7 +106,7 @@ Item {
106106 contentEndReachedSpy.clear()
107107 clear_scope_status();
108108
109− // clear, wait for dahs to empty and load scopes.
109+ // clear, wait for dash to empty and load scopes.
110110 var dashContentList = findChild(dashContent, "dashContentList");
111111 verify(dashContentList != undefined)
112112 scopesModel.clear();
tests/qmltests/Dash/tst_GenericScopeView.qml+17
@@ -44,10 +44,27 @@ Item {
4444
4545 function test_isCurrent() {
4646 var pageHeader = findChild(genericScopeView, "pageHeader");
47+ var previewLoader = findChild(genericScopeView, "previewLoader");
4748 genericScopeView.isCurrent = true
4849 pageHeader.searchQuery = "test"
50+ previewLoader.open = true
4951 genericScopeView.isCurrent = false
5052 tryCompare(pageHeader, "searchQuery", "")
53+ tryCompare(genericScopeView, "previewShown", false);
54+ }
55+
56+ function test_showDash() {
57+ var previewLoader = findChild(genericScopeView, "previewLoader");
58+ previewLoader.open = true;
59+ scopes.get(0).showDash();
60+ tryCompare(genericScopeView, "previewShown", false);
61+ }
62+
63+ function test_hideDash() {
64+ var previewLoader = findChild(genericScopeView, "previewLoader");
65+ previewLoader.open = true;
66+ scopes.get(0).hideDash();
67+ tryCompare(genericScopeView, "previewShown", false);
5168 }
5269 }
5370 }
tests/uqmlscene/main.cpp−2
@@ -497,8 +497,6 @@ int main(int argc, char ** argv)
497497 }
498498
499499 if (window) {
500− mouseTouchAdaptor.setTargetWindow(window);
501−
502500 QSurfaceFormat surfaceFormat = window->requestedFormat();
503501 if (options.multisample)
504502 surfaceFormat.setSamples(16);