on xenial help sign in
Merge from trunk
00a39ecMichael Terry
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
@@ -118,7 +118,7 @@ Item {
118 "edge": "bottom",
118 "edge": "bottom",
119 "title": i18n.tr("Close"),
119 "title": i18n.tr("Close"),
120 "text": i18n.tr("Swipe up again to close the settings screen"),
120 "text": i18n.tr("Swipe up again to close the settings screen"),
121− "anchors.fill": demo.indicators,
121+ "anchors.fill": demo.indicators.content,
122 });
122 });
123 }
123 }
124 if (d.bottomEdgeDemo) {
124 if (d.bottomEdgeDemo) {
Components/EdgeDemoOverlay.qml+3
@@ -153,7 +153,10 @@ Showable {
153 font.underline: true
153 font.underline: true
154
154
155 MouseArea {
155 MouseArea {
156+ // Make clickable area bigger than just the link because
157+ // otherwise, the edge demo will feel hard to dismiss.
156 anchors.fill: parent
158 anchors.fill: parent
159+ anchors.margins: -units.gu(5)
157 onClicked: overlay.doSkip()
160 onClicked: overlay.doSkip()
158 }
161 }
159 }
162 }
Components/ResponsiveGridView.qml+1−1
@@ -67,7 +67,7 @@ Item {
67
67
68 function columnsForSpacing(spacing) {
68 function columnsForSpacing(spacing) {
69 // minimum margin is half of the spacing
69 // 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)));
71 }
71 }
72
72
73 property real allocatableHorizontalSpace: parent.width - columns * delegateWidth
73 property real allocatableHorizontalSpace: parent.width - columns * delegateWidth
Dash/Apps/AppPreview.qml+11
@@ -110,6 +110,10 @@ DashPreview {
110 onFinished: {
110 onFinished: {
111 root.previewData.execute(progressBar.model[0].id, { })
111 root.previewData.execute(progressBar.model[0].id, { })
112 }
112 }
113+
114+ onError: {
115+ root.previewData.execute(progressBar.model[1].id, { "error": error });
116+ }
113 }
117 }
114
118
115 }
119 }
@@ -187,12 +191,19 @@ DashPreview {
187 ListItem.ThinDivider { }
191 ListItem.ThinDivider { }
188
192
189 AppReviews {
193 AppReviews {
194+ id: appReviews
190 objectName: "appReviews"
195 objectName: "appReviews"
196+ // TODO: This should make this visible when the feature for reviews/comments is complete.
197+ visible: false
191 anchors { left: parent.left; right: parent.right }
198 anchors { left: parent.left; right: parent.right }
192
199
193 model: root.previewData.infoMap["comments"] ? root.previewData.infoMap["comments"].value : undefined
200 model: root.previewData.infoMap["comments"] ? root.previewData.infoMap["comments"].value : undefined
194
201
195 onSendReview: root.sendUserReview(review);
202 onSendReview: root.sendUserReview(review);
203+
204+ onEditing: {
205+ root.ensureVisible(appReviews.textArea);
206+ }
196 }
207 }
197 }
208 }
198 }
209 }
Dash/Apps/AppReviews.qml+3
@@ -23,8 +23,10 @@ Column {
23 id: root
23 id: root
24
24
25 property var model
25 property var model
26+ property alias textArea: reviewField
26
27
27 signal sendReview(string review)
28 signal sendReview(string review)
29+ signal editing
28
30
29 spacing: units.gu(2)
31 spacing: units.gu(2)
30 state: ""
32 state: ""
@@ -93,6 +95,7 @@ Column {
93 if(reviewField.focus){
95 if(reviewField.focus){
94 root.state = "editing";
96 root.state = "editing";
95 reviewField.selectAll();
97 reviewField.selectAll();
98+ root.editing();
96 }
99 }
97 }
100 }
98
101
Dash/DashPreview.qml+13
@@ -20,6 +20,7 @@ import Ubuntu.Components 0.1
20Rectangle {
20Rectangle {
21 id: root
21 id: root
22
22
23+ property int keyboardSize: Qt.inputMethod.visible ? Qt.inputMethod.keyboardRectangle.height : 0
23 property var previewData
24 property var previewData
24
25
25 property string title: ""
26 property string title: ""
@@ -38,6 +39,14 @@ Rectangle {
38 color: Qt.rgba(0, 0, 0, .3)
39 color: Qt.rgba(0, 0, 0, .3)
39 clip: true
40 clip: true
40
41
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+
41 Connections {
50 Connections {
42 target: shell.applicationManager
51 target: shell.applicationManager
43 onMainStageFocusedApplicationChanged: {
52 onMainStageFocusedApplicationChanged: {
@@ -128,12 +137,16 @@ Rectangle {
128
137
129 Flickable {
138 Flickable {
130 id: leftFlickable
139 id: leftFlickable
140+ objectName: "leftFlickable"
131 anchors.top: parent.top
141 anchors.top: parent.top
132 anchors.bottom: parent.bottom
142 anchors.bottom: parent.bottom
133 width: root.narrowMode ? contentRow.width : contentRow.width * root.previewWidthRatio
143 width: root.narrowMode ? contentRow.width : contentRow.width * root.previewWidthRatio
134 contentHeight: leftColumn.height
144 contentHeight: leftColumn.height
145+ anchors.bottomMargin: root.keyboardSize
135 clip: true
146 clip: true
136
147
148+ Behavior on contentY { NumberAnimation { duration: 300 } }
149+
137 Column {
150 Column {
138 id: leftColumn
151 id: leftColumn
139 objectName: "leftColumn"
152 objectName: "leftColumn"
Dash/GenericScopeView.qml+20−7
@@ -36,6 +36,12 @@ ScopeView {
36 value: pageHeader.searchQuery
36 value: pageHeader.searchQuery
37 }
37 }
38
38
39+ Binding {
40+ target: pageHeader
41+ property: "searchQuery"
42+ value: scopeView.scope.searchQuery
43+ }
44+
39 Connections {
45 Connections {
40 target: panel
46 target: panel
41 onSearchClicked: if (isCurrent) {
47 onSearchClicked: if (isCurrent) {
@@ -44,6 +50,12 @@ ScopeView {
44 }
50 }
45 }
51 }
46
52
53+ Connections {
54+ target: scopeView.scope
55+ onShowDash: previewLoader.open = false;
56+ onHideDash: previewLoader.open = false;
57+ }
58+
47 ScopeListView {
59 ScopeListView {
48 id: categoryView
60 id: categoryView
49 anchors.fill: parent
61 anchors.fill: parent
@@ -53,13 +65,14 @@ ScopeView {
53 onAtYEndChanged: if (atYEnd) endReached()
65 onAtYEndChanged: if (atYEnd) endReached()
54 onMovingChanged: if (moving && atYEnd) endReached()
66 onMovingChanged: if (moving && atYEnd) endReached()
55
67
56− property int expandedIndex: -1
68+ property string expandedCategoryId: ""
57
69
58 delegate: ListItems.Base {
70 delegate: ListItems.Base {
59 highlightWhenPressed: false
71 highlightWhenPressed: false
60
72
61 readonly property bool expandable: rendererLoader.item ? rendererLoader.item.expandable : false
73 readonly property bool expandable: rendererLoader.item ? rendererLoader.item.expandable : false
62 readonly property bool filtered: rendererLoader.item ? rendererLoader.item.filter : true
74 readonly property bool filtered: rendererLoader.item ? rendererLoader.item.filter : true
75+ readonly property string category: categoryId
63
76
64 Loader {
77 Loader {
65 id: rendererLoader
78 id: rendererLoader
@@ -81,7 +94,7 @@ ScopeView {
81 }
94 }
82 item.objectName = Qt.binding(function() { return categoryId })
95 item.objectName = Qt.binding(function() { return categoryId })
83 if (item.expandable) {
96 if (item.expandable) {
84− var shouldFilter = index != categoryView.expandedIndex;
97+ var shouldFilter = categoryId != categoryView.expandedCategoryId;
85 if (shouldFilter != item.filter) {
98 if (shouldFilter != item.filter) {
86 item.filter = shouldFilter;
99 item.filter = shouldFilter;
87 }
100 }
@@ -117,10 +130,10 @@ ScopeView {
117 }
130 }
118 Connections {
131 Connections {
119 target: categoryView
132 target: categoryView
120− onExpandedIndexChanged: {
133+ onExpandedCategoryIdChanged: {
121 var item = rendererLoader.item;
134 var item = rendererLoader.item;
122 if (item.expandable) {
135 if (item.expandable) {
123− var shouldFilter = index != categoryView.expandedIndex;
136+ var shouldFilter = categoryId != categoryView.expandedCategoryId;
124 if (shouldFilter != item.filter) {
137 if (shouldFilter != item.filter) {
125 // If the filter animation will be seen start it, otherwise, just flip the switch
138 // If the filter animation will be seen start it, otherwise, just flip the switch
126 var shrinkingVisible = shouldFilter && y + item.collapsedHeight < categoryView.height;
139 var shrinkingVisible = shouldFilter && y + item.collapsedHeight < categoryView.height;
@@ -151,10 +164,10 @@ ScopeView {
151 return "";
164 return "";
152 }
165 }
153 onClicked: {
166 onClicked: {
154− if (categoryView.expandedIndex != delegateIndex)
167+ if (categoryView.expandedCategoryId != delegate.category)
155− categoryView.expandedIndex = delegateIndex;
168+ categoryView.expandedCategoryId = delegate.category;
156 else
169 else
157− categoryView.expandedIndex = -1;
170+ categoryView.expandedCategoryId = "";
158 }
171 }
159 }
172 }
160 pageHeader: PageHeader {
173 pageHeader: PageHeader {
Dash/Music/MusicFilterGrid.qml+12−2
@@ -29,19 +29,29 @@ FilterGrid {
29 readonly property int iconWidth: (width / columns) * 0.8
29 readonly property int iconWidth: (width / columns) * 0.8
30 readonly property int iconHeight: iconWidth
30 readonly property int iconHeight: iconWidth
31
31
32− signal clicked(int index)
32+ signal clicked(int index, var delegateItem, real itemY)
33+ signal pressAndHold(int index, var delegateItem, real itemY)
33
34
34 delegate: AlbumTile {
35 delegate: AlbumTile {
36+ id: tile
35 objectName: "delegate" + index
37 objectName: "delegate" + index
36 width: filterGrid.cellWidth
38 width: filterGrid.cellWidth
37 height: filterGrid.cellHeight
39 height: filterGrid.cellHeight
38 iconWidth: filterGrid.iconWidth
40 iconWidth: filterGrid.iconWidth
39 iconHeight: filterGrid.iconHeight
41 iconHeight: filterGrid.iconHeight
42+
40 artist: model.title
43 artist: model.title
41 album: model.comment
44 album: model.comment
42 source: model.icon
45 source: model.icon
46+
43 onClicked: {
47 onClicked: {
48+ var data = { model: model }
44− filterGrid.clicked(index);
49+ filterGrid.clicked(index, data, tile.y)
50+ }
51+
52+ onPressAndHold: {
53+ var data = { model: model }
54+ filterGrid.pressAndHold(index, data, tile.y)
45 }
55 }
46 }
56 }
47}
57}
Greeter/Greeter.qml+1−1
@@ -61,8 +61,8 @@ Showable {
61 id: backgroundImage
61 id: backgroundImage
62 objectName: "backgroundImage"
62 objectName: "backgroundImage"
63 anchors.fill: parent
63 anchors.fill: parent
64− fadeInFirst: false
65 source: greeter.background
64 source: greeter.background
65+ fillMode: Image.PreserveAspectCrop
66 }
66 }
67
67
68 Loader {
68 Loader {
Panel/Indicators.qml+1
@@ -35,6 +35,7 @@ Showable {
35 property bool partiallyOpened: height > panelHeight && !fullyOpened
35 property bool partiallyOpened: height > panelHeight && !fullyOpened
36 property real visualBottom: Math.max(y+height, y+indicatorRow.y+indicatorRow.height)
36 property real visualBottom: Math.max(y+height, y+indicatorRow.y+indicatorRow.height)
37 property bool contentEnabled: true
37 property bool contentEnabled: true
38+ readonly property alias content: menuContent
38
39
39 // TODO: Perhaps we need a animation standard for showing/hiding? Each showable seems to
40 // TODO: Perhaps we need a animation standard for showing/hiding? Each showable seems to
40 // use its own values. Need to ask design about this.
41 // use its own values. Need to ask design about this.
Panel/MenuContent.qml+12−2
@@ -109,7 +109,7 @@ MainView {
109 source: pageSource
109 source: pageSource
110 asynchronous: true
110 asynchronous: true
111
111
112− property bool contentActive: content.__contentActive
112+ property bool contentActive: content.__contentActive && menuActivator.content[index].active
113
113
114 onContentActiveChanged: {
114 onContentActiveChanged: {
115 if (contentActive && item) {
115 if (contentActive && item) {
@@ -146,6 +146,16 @@ MainView {
146 id: contentReleaseTimer
146 id: contentReleaseTimer
147
147
148 interval: contentReleaseInterval
148 interval: contentReleaseInterval
149+ onTriggered: {
149− onTriggered: content.__contentActive = false
150+ content.__contentActive = false;
151+ menuActivator.clear();
152+ }
153+ }
154+
155+ Indicators.MenuContentActivator {
156+ id: menuActivator
157+ running: content.__contentActive
158+ baseIndex: content.currentMenuIndex
159+ count: indicatorsModel.count
150 }
160 }
151}
161}
Shell.qml+2−1
@@ -149,6 +149,7 @@ BasicShell {
149
149
150 anchors.fill: parent
150 anchors.fill: parent
151 source: shell.background
151 source: shell.background
152+ fillMode: Image.PreserveAspectCrop
152 }
153 }
153
154
154 Rectangle {
155 Rectangle {
@@ -474,7 +475,7 @@ BasicShell {
474 Bottombar {
475 Bottombar {
475 theHud: hud
476 theHud: hud
476 anchors.fill: parent
477 anchors.fill: parent
477− enabled: !panel.indicators.shown
478+ enabled: hud.available
478 applicationIsOnForeground: applicationFocused
479 applicationIsOnForeground: applicationFocused
479 }
480 }
480
481
debian/changelog+68
@@ -1,3 +1,71 @@
1+unity8 (7.81.3+13.10.20130924.2-0ubuntu1) saucy; urgency=low
2+
3+ [ Michal Hruby ]
4+ * Fix the signal prototypes on music grid renderer. (LP: #1228390)
5+
6+ [ Michael Zanetti ]
7+ * use less auto variables, align coding style, constify and Qt'ify API
8+ in AccountsService plugin.
9+
10+ [ Nick Dedekind ]
11+ * Re-enable MenuContentActivator in Indicators.
12+
13+ [ Albert Astals ]
14+ * LVWPH: Update the section header on list change events.
15+
16+ [ Pawel Stolowski ]
17+ * Check results model ptr returned by GetResultsFromCategory method
18+ from UnityCore. (LP: #1228097, #1211595)
19+
20+ [ Ubuntu daily release ]
21+ * Automatic snapshot from revision 340
22+
23+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 24 Sep 2013 14:40:01 +0000
24+
25+unity8 (7.81.3+13.10.20130919.3-0ubuntu1) saucy; urgency=low
26+
27+ [ Michal Hruby ]
28+ * Add support for music grid renderer to GenericScopeView.
29+
30+ [ Nick Dedekind ]
31+ * Fixed the removal of messaging widget due to incompatible action
32+ state. (LP: #1225017)
33+
34+ [ Christopher Lee ]
35+ * Addition of initial autopilot tests for the application lifecycle.
36+
37+ [ Lars Uebernickel ]
38+ * VolumeControl: use action of the new indicator indicator-sound
39+ recently gained an action to increase and decrease the volume. This
40+ patch makes use of that to get rid of a bus round trip (to get the
41+ current volume) and a race (when the volume gets set between
42+ fetching the current volume and setting the new volume). (LP:
43+ #1219057)
44+
45+ [ Michael Terry ]
46+ * When AccountsService.backgroundFile is unset/invalid, have the
47+ greeter fall back to whatever the shell background is.
48+ * Add a tiny SessionBroadcast plugin that listens to unity-greeter-
49+ session-broadcast for the ShowHome signal.
50+
51+ [ Daniel d'Andrada ]
52+ * Remove obsolete, unused graphics.
53+ * Make MouseTouchAdaptor work with multiple QWindows.
54+
55+ [ Michael Zanetti ]
56+ * change how icons are searched a) try to find it the Icon as is b)
57+ prepend with Path if a Path variable is given c) fall back to the
58+ image://theme/ with just the icon name . (LP: #1225186)
59+ * fix an issue with removing a running app from the launcher and
60+ always store pinning to the config.
61+ * collapse any open preview when programmatically switching current
62+ dash index. (LP: #1221137)
63+
64+ [ Ubuntu daily release ]
65+ * Automatic snapshot from revision 333
66+
67+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Thu, 19 Sep 2013 15:15:07 +0000
68+
1unity8 (7.81.3+13.10.20130916-0ubuntu1) saucy; urgency=low
69unity8 (7.81.3+13.10.20130916-0ubuntu1) saucy; urgency=low
2
70
3 [ Michael Zanetti ]
71 [ Michael Zanetti ]
plugins/AccountsService/AccountsService.cpp+4−4
@@ -34,7 +34,7 @@ AccountsService::AccountsService(QObject* parent)
34 updateDemoEdgesForCurrentUser();
34 updateDemoEdgesForCurrentUser();
35}
35}
36
36
37−QString AccountsService::getUser()
37+QString AccountsService::user() const
38{
38{
39 return m_user;
39 return m_user;
40}
40}
@@ -48,7 +48,7 @@ void AccountsService::setUser(const QString &user)
48 updateBackgroundFile();
48 updateBackgroundFile();
49}
49}
50
50
51−bool AccountsService::getDemoEdges()
51+bool AccountsService::demoEdges() const
52{
52{
53 return m_demoEdges;
53 return m_demoEdges;
54}
54}
@@ -59,7 +59,7 @@ void AccountsService::setDemoEdges(bool demoEdges)
59 m_service->setUserProperty(m_user, "com.canonical.unity.AccountsService", "demo-edges", demoEdges);
59 m_service->setUserProperty(m_user, "com.canonical.unity.AccountsService", "demo-edges", demoEdges);
60}
60}
61
61
62−bool AccountsService::getDemoEdgesForCurrentUser()
62+bool AccountsService::demoEdgesForCurrentUser() const
63{
63{
64 return m_demoEdgesForCurrentUser;
64 return m_demoEdgesForCurrentUser;
65}
65}
@@ -70,7 +70,7 @@ void AccountsService::setDemoEdgesForCurrentUser(bool demoEdgesForCurrentUser)
70 m_service->setUserProperty(qgetenv("USER"), "com.canonical.unity.AccountsService", "demo-edges", demoEdgesForCurrentUser);
70 m_service->setUserProperty(qgetenv("USER"), "com.canonical.unity.AccountsService", "demo-edges", demoEdgesForCurrentUser);
71}
71}
72
72
73−QString AccountsService::getBackgroundFile()
73+QString AccountsService::backgroundFile() const
74{
74{
75 return m_backgroundFile;
75 return m_backgroundFile;
76}
76}
plugins/AccountsService/AccountsService.h+8−8
@@ -28,31 +28,31 @@ class AccountsService: public QObject
28{
28{
29 Q_OBJECT
29 Q_OBJECT
30 Q_PROPERTY (QString user
30 Q_PROPERTY (QString user
31− READ getUser
31+ READ user
32 WRITE setUser
32 WRITE setUser
33 NOTIFY userChanged)
33 NOTIFY userChanged)
34 Q_PROPERTY (bool demoEdges
34 Q_PROPERTY (bool demoEdges
35− READ getDemoEdges
35+ READ demoEdges
36 WRITE setDemoEdges
36 WRITE setDemoEdges
37 NOTIFY demoEdgesChanged)
37 NOTIFY demoEdgesChanged)
38 Q_PROPERTY (bool demoEdgesForCurrentUser
38 Q_PROPERTY (bool demoEdgesForCurrentUser
39− READ getDemoEdgesForCurrentUser
39+ READ demoEdgesForCurrentUser
40 WRITE setDemoEdgesForCurrentUser
40 WRITE setDemoEdgesForCurrentUser
41 NOTIFY demoEdgesForCurrentUserChanged)
41 NOTIFY demoEdgesForCurrentUserChanged)
42 Q_PROPERTY (QString backgroundFile
42 Q_PROPERTY (QString backgroundFile
43− READ getBackgroundFile
43+ READ backgroundFile
44 NOTIFY backgroundFileChanged)
44 NOTIFY backgroundFileChanged)
45
45
46public:
46public:
47 explicit AccountsService(QObject *parent = 0);
47 explicit AccountsService(QObject *parent = 0);
48
48
49− QString getUser();
49+ QString user() const;
50 void setUser(const QString &user);
50 void setUser(const QString &user);
51− bool getDemoEdges();
51+ bool demoEdges() const;
52 void setDemoEdges(bool demoEdges);
52 void setDemoEdges(bool demoEdges);
53− bool getDemoEdgesForCurrentUser();
53+ bool demoEdgesForCurrentUser() const;
54 void setDemoEdgesForCurrentUser(bool demoEdgesForCurrentUser);
54 void setDemoEdgesForCurrentUser(bool demoEdgesForCurrentUser);
55− QString getBackgroundFile();
55+ QString backgroundFile() const;
56
56
57Q_SIGNALS:
57Q_SIGNALS:
58 void userChanged();
58 void userChanged();
plugins/AccountsService/AccountsServiceDBusAdaptor.cpp+15−15
@@ -24,13 +24,13 @@
24
24
25AccountsServiceDBusAdaptor::AccountsServiceDBusAdaptor(QObject* parent)
25AccountsServiceDBusAdaptor::AccountsServiceDBusAdaptor(QObject* parent)
26 : QObject(parent),
26 : QObject(parent),
27− accounts_manager(NULL),
27+ m_accountsManager(NULL),
28− users()
28+ m_users()
29{
29{
30− auto connection = QDBusConnection::SM_BUSNAME();
30+ QDBusConnection connection = QDBusConnection::SM_BUSNAME();
31− auto interface = connection.interface();
31+ QDBusConnectionInterface *interface = connection.interface();
32 interface->startService("org.freedesktop.Accounts");
32 interface->startService("org.freedesktop.Accounts");
33− accounts_manager = new QDBusInterface("org.freedesktop.Accounts",
33+ m_accountsManager = new QDBusInterface("org.freedesktop.Accounts",
34 "/org/freedesktop/Accounts",
34 "/org/freedesktop/Accounts",
35 "org.freedesktop.Accounts",
35 "org.freedesktop.Accounts",
36 connection, this);
36 connection, this);
@@ -38,9 +38,9 @@ AccountsServiceDBusAdaptor::AccountsServiceDBusAdaptor(QObject* parent)
38
38
39QVariant AccountsServiceDBusAdaptor::getUserProperty(const QString &user, const QString &interface, const QString &property)
39QVariant AccountsServiceDBusAdaptor::getUserProperty(const QString &user, const QString &interface, const QString &property)
40{
40{
41− auto iface = getUserInterface(user);
41+ QDBusInterface *iface = getUserInterface(user);
42 if (iface != nullptr && iface->isValid()) {
42 if (iface != nullptr && iface->isValid()) {
43− auto answer = iface->call("Get", interface, property);
43+ QDBusMessage answer = iface->call("Get", interface, property);
44 if (answer.type() == QDBusMessage::ReplyMessage) {
44 if (answer.type() == QDBusMessage::ReplyMessage) {
45 return answer.arguments()[0].value<QDBusVariant>().variant();
45 return answer.arguments()[0].value<QDBusVariant>().variant();
46 }
46 }
@@ -50,7 +50,7 @@ QVariant AccountsServiceDBusAdaptor::getUserProperty(const QString &user, const
50
50
51void AccountsServiceDBusAdaptor::setUserProperty(const QString &user, const QString &interface, const QString &property, const QVariant &value)
51void AccountsServiceDBusAdaptor::setUserProperty(const QString &user, const QString &interface, const QString &property, const QVariant &value)
52{
52{
53− auto iface = getUserInterface(user);
53+ QDBusInterface *iface = getUserInterface(user);
54 if (iface != nullptr && iface->isValid()) {
54 if (iface != nullptr && iface->isValid()) {
55 // The value needs to be carefully wrapped
55 // The value needs to be carefully wrapped
56 iface->call("Set", interface, property, QVariant::fromValue(QDBusVariant(value)));
56 iface->call("Set", interface, property, QVariant::fromValue(QDBusVariant(value)));
@@ -76,7 +76,7 @@ void AccountsServiceDBusAdaptor::maybeChangedSlot()
76QString AccountsServiceDBusAdaptor::getUserForPath(const QString &path)
76QString AccountsServiceDBusAdaptor::getUserForPath(const QString &path)
77{
77{
78 QMap<QString, QDBusInterface *>::const_iterator i;
78 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) {
80 if (i.value()->path() == path) {
80 if (i.value()->path() == path) {
81 return i.key();
81 return i.key();
82 }
82 }
@@ -86,16 +86,16 @@ QString AccountsServiceDBusAdaptor::getUserForPath(const QString &path)
86
86
87QDBusInterface *AccountsServiceDBusAdaptor::getUserInterface(const QString &user)
87QDBusInterface *AccountsServiceDBusAdaptor::getUserInterface(const QString &user)
88{
88{
89− auto iface = users.value(user);
89+ QDBusInterface *iface = m_users.value(user);
90− if (iface == nullptr && accounts_manager->isValid()) {
90+ if (iface == nullptr && m_accountsManager->isValid()) {
91− auto answer = accounts_manager->call("FindUserByName", user);
91+ QDBusMessage answer = m_accountsManager->call("FindUserByName", user);
92 if (answer.type() == QDBusMessage::ReplyMessage) {
92 if (answer.type() == QDBusMessage::ReplyMessage) {
93− auto path = answer.arguments()[0].value<QDBusObjectPath>().path();
93+ QString path = answer.arguments()[0].value<QDBusObjectPath>().path();
94
94
95 iface = new QDBusInterface("org.freedesktop.Accounts",
95 iface = new QDBusInterface("org.freedesktop.Accounts",
96 path,
96 path,
97 "org.freedesktop.DBus.Properties",
97 "org.freedesktop.DBus.Properties",
98− accounts_manager->connection(), this);
98+ m_accountsManager->connection(), this);
99
99
100 // With its own pre-defined properties, AccountsService is oddly
100 // With its own pre-defined properties, AccountsService is oddly
101 // close-lipped. It won't send out proper DBus.Properties notices,
101 // close-lipped. It won't send out proper DBus.Properties notices,
@@ -119,7 +119,7 @@ QDBusInterface *AccountsServiceDBusAdaptor::getUserInterface(const QString &user
119 this,
119 this,
120 SLOT(propertiesChangedSlot(QString, QVariantMap, QStringList)));
120 SLOT(propertiesChangedSlot(QString, QVariantMap, QStringList)));
121
121
122− users.insert(user, iface);
122+ m_users.insert(user, iface);
123 }
123 }
124 }
124 }
125 return iface;
125 return iface;
plugins/AccountsService/AccountsServiceDBusAdaptor.h+2−2
@@ -47,8 +47,8 @@ private:
47 QDBusInterface *getUserInterface(const QString &user);
47 QDBusInterface *getUserInterface(const QString &user);
48 QString getUserForPath(const QString &path);
48 QString getUserForPath(const QString &path);
49
49
50− QDBusInterface *accounts_manager;
50+ QDBusInterface *m_accountsManager;
51− QMap<QString, QDBusInterface *> users;
51+ QMap<QString, QDBusInterface *> m_users;
52};
52};
53
53
54#endif
54#endif
plugins/ListViewWithPageHeader/listviewwithpageheader.cpp+15
@@ -170,6 +170,8 @@ ListViewWithPageHeader::ListViewWithPageHeader()
170 connect(this, SIGNAL(contentHeightChanged()), this, SLOT(onContentHeightChanged()));
170 connect(this, SIGNAL(contentHeightChanged()), this, SLOT(onContentHeightChanged()));
171 connect(this, SIGNAL(heightChanged()), this, SLOT(onHeightChanged()));
171 connect(this, SIGNAL(heightChanged()), this, SLOT(onHeightChanged()));
172 connect(m_contentYAnimation, SIGNAL(stopped()), this, SLOT(onShowHeaderAnimationFinished()));
172 connect(m_contentYAnimation, SIGNAL(stopped()), this, SLOT(onShowHeaderAnimationFinished()));
173+
174+ setFlickableDirection(VerticalFlick);
173}
175}
174
176
175ListViewWithPageHeader::~ListViewWithPageHeader()
177ListViewWithPageHeader::~ListViewWithPageHeader()
@@ -199,6 +201,7 @@ void ListViewWithPageHeader::setModel(QAbstractItemModel *model)
199 connect(m_delegateModel, SIGNAL(modelUpdated(QQmlChangeSet,bool)), this, SLOT(onModelUpdated(QQmlChangeSet,bool)));
201 connect(m_delegateModel, SIGNAL(modelUpdated(QQmlChangeSet,bool)), this, SLOT(onModelUpdated(QQmlChangeSet,bool)));
200#endif
202#endif
201 Q_EMIT modelChanged();
203 Q_EMIT modelChanged();
204+ polish();
202 // TODO?
205 // TODO?
203// Q_EMIT contentHeightChanged();
206// Q_EMIT contentHeightChanged();
204// Q_EMIT contentYChanged();
207// Q_EMIT contentYChanged();
@@ -1006,6 +1009,18 @@ void ListViewWithPageHeader::onModelUpdated(const QQmlChangeSet &changeSet, bool
1006 }
1009 }
1007 }
1010 }
1008
1011
1012+ Q_FOREACH(const QQuickChangeSet::Change &change, changeSet.changes()) {
1013+// qDebug() << "ListViewWithPageHeader::onModelUpdated Change" << change.index << change.count;
1014+ for (int i = change.index; i < change.count; ++i) {
1015+ ListItem *item = itemAtIndex(i);
1016+ if (item && item->m_sectionItem) {
1017+ QQmlContext *context = QQmlEngine::contextForObject(item->m_sectionItem)->parentContext();
1018+ const QString sectionText = m_delegateModel->stringValue(i, m_sectionProperty);
1019+ context->setContextProperty(QLatin1String("section"), sectionText);
1020+ }
1021+ }
1022+ }
1023+
1009 if (m_firstVisibleIndex != oldFirstVisibleIndex) {
1024 if (m_firstVisibleIndex != oldFirstVisibleIndex) {
1010 adjustMinYExtent();
1025 adjustMinYExtent();
1011 }
1026 }
plugins/ListViewWithPageHeader/listviewwithpageheader.h+1
@@ -63,6 +63,7 @@ class ListViewWithPageHeader : public QQuickFlickable, public QQuickItemChangeLi
63
63
64 friend class ListViewWithPageHeaderTest;
64 friend class ListViewWithPageHeaderTest;
65 friend class ListViewWithPageHeaderTestSection;
65 friend class ListViewWithPageHeaderTestSection;
66+ friend class ListViewWithPageHeaderTestExternalModel;
66
67
67public:
68public:
68 ListViewWithPageHeader();
69 ListViewWithPageHeader();
plugins/Unity/categories.cpp+12−1
@@ -21,6 +21,7 @@
21// self
21// self
22#include "categories.h"
22#include "categories.h"
23#include "categoryresults.h"
23#include "categoryresults.h"
24+#include <QDebug>
24
25
25// TODO: use something from libunity once it's public
26// TODO: use something from libunity once it's public
26enum CategoryColumn {
27enum CategoryColumn {
@@ -62,7 +63,17 @@ Categories::getResults(int index) const
62
63
63 unsigned categoryIndex = static_cast<unsigned>(index);
64 unsigned categoryIndex = static_cast<unsigned>(index);
64 auto unity_results = m_unityScope->GetResultsForCategory(categoryIndex);
65 auto unity_results = m_unityScope->GetResultsForCategory(categoryIndex);
66+ if (unity_results) {
65− results->setModel(unity_results->model());
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+ }
66
77
67 m_results.insert(index, results);
78 m_results.insert(index, results);
68 }
79 }
plugins/Unity/iconutils.cpp+1−1
@@ -30,7 +30,7 @@ QString gIconToDeclarativeImageProviderString(QString const &giconString)
30 if (giconString.isEmpty()) return giconString;
30 if (giconString.isEmpty()) return giconString;
31
31
32 if (giconString.startsWith('/') || giconString.startsWith(QLatin1String("http")) ||
32 if (giconString.startsWith('/') || giconString.startsWith(QLatin1String("http")) ||
33− giconString.startsWith(QLatin1String("file:"))) {
33+ giconString.startsWith(QLatin1String("file:")) || giconString.startsWith(QLatin1String("image:"))) {
34 return giconString;
34 return giconString;
35 }
35 }
36
36
plugins/Unity/scope.cpp+13−1
@@ -175,7 +175,12 @@ void Scope::preview(const QVariant &uri, const QVariant &icon_hint, const QVaria
175 const QVariant &comment, const QVariant &dnd_uri, const QVariant &metadata)
175 const QVariant &comment, const QVariant &dnd_uri, const QVariant &metadata)
176{
176{
177 auto res = createLocalResult(uri, icon_hint, category, result_type, mimetype, title, comment, dnd_uri, metadata);
177 auto res = createLocalResult(uri, icon_hint, category, result_type, mimetype, title, comment, dnd_uri, metadata);
178+ // canned queries don't have previews, must be activated
179+ if (uri.toString().startsWith("x-unity-no-preview-scopes-query://")) {
180+ m_unityScope->Activate(res);
181+ } else {
178− m_unityScope->Preview(res);
182+ m_unityScope->Preview(res);
183+ }
179}
184}
180
185
181void Scope::onActivated(unity::dash::LocalResult const& result, unity::dash::ScopeHandledType type, unity::glib::HintsMap const& hints)
186void Scope::onActivated(unity::dash::LocalResult const& result, unity::dash::ScopeHandledType type, unity::glib::HintsMap const& hints)
@@ -199,6 +204,13 @@ void Scope::onActivated(unity::dash::LocalResult const& result, unity::dash::Sco
199 qWarning() << "Missing goto-uri hint for GOTO_DASH_URI activation reply";
204 qWarning() << "Missing goto-uri hint for GOTO_DASH_URI activation reply";
200 }
205 }
201 break;
206 break;
207+ case unity::dash::PERFORM_SEARCH:
208+ if (hints.find("query") != hints.end()) {
209+ // note: this will emit searchQueryChanged, and shell will call setSearchQuery back with a new query,
210+ // but it will get ignored.
211+ setSearchQuery(QString::fromStdString(g_variant_get_string(hints.at("query"), nullptr)));
212+ }
213+ break;
202 default:
214 default:
203 qWarning() << "Unhandled activation response:" << type;
215 qWarning() << "Unhandled activation response:" << type;
204 }
216 }
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/sl.po+29−24
@@ -8,7 +8,7 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-08-27 13:36-0400\n"
10"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-19 19:48+0000\n"
12"Last-Translator: Damir Jerovšek <Unknown>\n"
12"Last-Translator: Damir Jerovšek <Unknown>\n"
13"Language-Team: Slovenian <sl@li.org>\n"
13"Language-Team: Slovenian <sl@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
@@ -16,8 +16,8 @@ msgstr ""
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || "
17"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || "
18"n%100==4 ? 3 : 0);\n"
18"n%100==4 ? 3 : 0);\n"
19−"X-Launchpad-Export-Date: 2013-08-30 05:37+0000\n"
19+"X-Launchpad-Export-Date: 2013-09-20 06:21+0000\n"
20−"X-Generator: Launchpad (build 16750)\n"
20+"X-Generator: Launchpad (build 16765)\n"
21
21
22#: Applications/applications.js:23
22#: Applications/applications.js:23
23msgid "Phone"
23msgid "Phone"
@@ -25,7 +25,7 @@ msgstr "Telefon"
25
25
26#: Applications/applications.js:29
26#: Applications/applications.js:29
27msgid "Camera"
27msgid "Camera"
28−msgstr ""
28+msgstr "Fotoaparat"
29
29
30#: Applications/applications.js:35
30#: Applications/applications.js:35
31msgid "Gallery"
31msgid "Gallery"
@@ -89,47 +89,50 @@ msgstr "YouTube"
89
89
90#: Components/EdgeDemoOverlay.qml:145
90#: Components/EdgeDemoOverlay.qml:145
91msgid "Skip intro"
91msgid "Skip intro"
92−msgstr ""
92+msgstr "Preskoči uvod"
93
93
94#: Components/EdgeDemo.qml:98
94#: Components/EdgeDemo.qml:98
95msgid "Right edge"
95msgid "Right edge"
96−msgstr ""
96+msgstr "Desni rob"
97
97
98#: Components/EdgeDemo.qml:99
98#: Components/EdgeDemo.qml:99
99msgid "Try swiping from the right edge to unlock the phone"
99msgid "Try swiping from the right edge to unlock the phone"
100−msgstr ""
100+msgstr "Poskusite povleči od desnega roba za odklep telefona"
101
101
102#: Components/EdgeDemo.qml:135
102#: Components/EdgeDemo.qml:135
103msgid "Top edge"
103msgid "Top edge"
104−msgstr ""
104+msgstr "Zgornji rob"
105
105
106#: Components/EdgeDemo.qml:136
106#: Components/EdgeDemo.qml:136
107msgid "Try swiping from the top edge to access the indicators"
107msgid "Try swiping from the top edge to access the indicators"
108−msgstr ""
108+msgstr "Poskusite povleči od zgornjega roba za dostop do kazalnikov"
109
109
110#: Components/EdgeDemo.qml:161
110#: Components/EdgeDemo.qml:161
111msgid "Close"
111msgid "Close"
112−msgstr ""
112+msgstr "Zapri"
113
113
114#: Components/EdgeDemo.qml:162
114#: Components/EdgeDemo.qml:162
115msgid "Swipe up again to close the settings screen"
115msgid "Swipe up again to close the settings screen"
116−msgstr ""
116+msgstr "Povlecite ponovno navzgor za zaprtje zaslona z nastavitvami"
117
117
118#: Components/EdgeDemo.qml:189
118#: Components/EdgeDemo.qml:189
119msgid "Left edge"
119msgid "Left edge"
120−msgstr ""
120+msgstr "Levi rob"
121
121
122#: Components/EdgeDemo.qml:190
122#: Components/EdgeDemo.qml:190
123msgid "Swipe from the left to reveal the launcher for quick access to apps"
123msgid "Swipe from the left to reveal the launcher for quick access to apps"
124msgstr ""
124msgstr ""
125+"Poskusite povleči od leve za razkritje zaganjalnika za hiter dostop do "
126+"programov"
125
127
126#: Components/EdgeDemo.qml:217
128#: Components/EdgeDemo.qml:217
127msgid "Well done"
129msgid "Well done"
128−msgstr ""
130+msgstr "Odlično"
129
131
130#: Components/EdgeDemo.qml:218
132#: Components/EdgeDemo.qml:218
131msgid "You have now mastered the edge gestures and can start using the phone"
133msgid "You have now mastered the edge gestures and can start using the phone"
132msgstr ""
134msgstr ""
135+"Zdaj, ko ste osvojili kretnje z robovi, lahko začnete uporabljati telefon"
133
136
134#: Components/PageHeader.qml:298
137#: Components/PageHeader.qml:298
135msgid "Recent searches"
138msgid "Recent searches"
@@ -139,35 +142,37 @@ msgstr "Nedavna iskanja"
139#: Dash/Apps/AppInfo.qml:73
142#: Dash/Apps/AppInfo.qml:73
140#, qt-format
143#, qt-format
141msgid "(%1)"
144msgid "(%1)"
142−msgstr ""
145+msgstr "(%1)"
143
146
144#. TRANSLATORS: Number of persons who wrote reviews for this app
147#. TRANSLATORS: Number of persons who wrote reviews for this app
145#: Dash/Apps/AppInfo.qml:85
148#: Dash/Apps/AppInfo.qml:85
146#, qt-format
149#, qt-format
147msgid "%1 review"
150msgid "%1 review"
148msgid_plural "%1 reviews"
151msgid_plural "%1 reviews"
149−msgstr[0] ""
152+msgstr[0] "%1 ocen"
153+msgstr[1] "%1 ocena"
150−msgstr[1] ""
154+msgstr[2] "%1 oceni"
155+msgstr[3] "%1 ocene"
151
156
152#: Dash/Apps/AppPreview.qml:175
157#: Dash/Apps/AppPreview.qml:175
153msgid "Rate this"
158msgid "Rate this"
154−msgstr ""
159+msgstr "Ocenite"
155
160
156#: Dash/Apps/AppReviews.qml:72
161#: Dash/Apps/AppReviews.qml:72
157msgid "Add a review"
162msgid "Add a review"
158−msgstr ""
163+msgstr "Dodaj oceno"
159
164
160#: Dash/Apps/AppReviews.qml:84
165#: Dash/Apps/AppReviews.qml:84
161msgid "Review"
166msgid "Review"
162−msgstr ""
167+msgstr "Ocena"
163
168
164#: Dash/Apps/AppReviews.qml:118
169#: Dash/Apps/AppReviews.qml:118
165msgid "Send"
170msgid "Send"
166−msgstr ""
171+msgstr "Pošlji"
167
172
168#: Dash/Apps/AppReviews.qml:136
173#: Dash/Apps/AppReviews.qml:136
169msgid "Comments:"
174msgid "Comments:"
170−msgstr ""
175+msgstr "Opombe:"
171
176
172#: Dash/DashMusic.qml:27 Dash/DashVideos.qml:28
177#: Dash/DashMusic.qml:27 Dash/DashVideos.qml:28
173msgid "Featured"
178msgid "Featured"
@@ -211,7 +216,7 @@ msgstr ""
211
216
212#: Greeter/Lockscreen.qml:134
217#: Greeter/Lockscreen.qml:134
213msgid "Emergency Call"
218msgid "Emergency Call"
214−msgstr ""
219+msgstr "Klic v sili"
215
220
216#: Greeter/PassphraseLockscreen.qml:59
221#: Greeter/PassphraseLockscreen.qml:59
217#, qt-format
222#, qt-format
@@ -220,7 +225,7 @@ msgstr "Pozdravljeni, %1"
220
225
221#: Greeter/PassphraseLockscreen.qml:59
226#: Greeter/PassphraseLockscreen.qml:59
222msgid "Hello"
227msgid "Hello"
223−msgstr ""
228+msgstr "Pozdravljeni"
224
229
225#: Hud/HudParametrizedActionsPage.qml:132
230#: Hud/HudParametrizedActionsPage.qml:132
226msgid "Confirm"
231msgid "Confirm"
@@ -253,4 +258,4 @@ msgstr "Nič se ne ujema z vašim iskalnim nizom."
253#: Shell.qml:429
258#: Shell.qml:429
254#, qt-format
259#, qt-format
255msgid "Please enter %1"
260msgid "Please enter %1"
256−msgstr ""
261+msgstr "Vnesite %1"
tests/mocks/AccountsService/AccountsService.cpp+4−4
@@ -24,7 +24,7 @@ AccountsService::AccountsService(QObject* parent)
24{
24{
25}
25}
26
26
27−QString AccountsService::getUser()
27+QString AccountsService::user() const
28{
28{
29 return "testuser";
29 return "testuser";
30}
30}
@@ -34,7 +34,7 @@ void AccountsService::setUser(const QString &user)
34 Q_UNUSED(user)
34 Q_UNUSED(user)
35}
35}
36
36
37−bool AccountsService::getDemoEdges()
37+bool AccountsService::demoEdges() const
38{
38{
39 return false;
39 return false;
40}
40}
@@ -44,7 +44,7 @@ void AccountsService::setDemoEdges(bool demoEdges)
44 Q_UNUSED(demoEdges)
44 Q_UNUSED(demoEdges)
45}
45}
46
46
47−bool AccountsService::getDemoEdgesForCurrentUser()
47+bool AccountsService::demoEdgesForCurrentUser() const
48{
48{
49 return false;
49 return false;
50}
50}
@@ -53,7 +53,7 @@ void AccountsService::setDemoEdgesForCurrentUser(bool)
53{
53{
54}
54}
55
55
56−QString AccountsService::getBackgroundFile()
56+QString AccountsService::backgroundFile() const
57{
57{
58 return m_backgroundFile;
58 return m_backgroundFile;
59}
59}
tests/mocks/AccountsService/AccountsService.h+8−8
@@ -28,32 +28,32 @@ class AccountsService: public QObject
28{
28{
29 Q_OBJECT
29 Q_OBJECT
30 Q_PROPERTY (QString user
30 Q_PROPERTY (QString user
31− READ getUser
31+ READ user
32 WRITE setUser
32 WRITE setUser
33 NOTIFY userChanged)
33 NOTIFY userChanged)
34 Q_PROPERTY (bool demoEdges
34 Q_PROPERTY (bool demoEdges
35− READ getDemoEdges
35+ READ demoEdges
36 WRITE setDemoEdges
36 WRITE setDemoEdges
37 NOTIFY demoEdgesChanged)
37 NOTIFY demoEdgesChanged)
38 Q_PROPERTY (bool demoEdgesForCurrentUser
38 Q_PROPERTY (bool demoEdgesForCurrentUser
39− READ getDemoEdgesForCurrentUser
39+ READ demoEdgesForCurrentUser
40 WRITE setDemoEdgesForCurrentUser
40 WRITE setDemoEdgesForCurrentUser
41 NOTIFY demoEdgesForCurrentUserChanged)
41 NOTIFY demoEdgesForCurrentUserChanged)
42 Q_PROPERTY (QString backgroundFile
42 Q_PROPERTY (QString backgroundFile
43− READ getBackgroundFile
43+ READ backgroundFile
44 WRITE setBackgroundFile // only available in mock
44 WRITE setBackgroundFile // only available in mock
45 NOTIFY backgroundFileChanged)
45 NOTIFY backgroundFileChanged)
46
46
47public:
47public:
48 explicit AccountsService(QObject *parent = 0);
48 explicit AccountsService(QObject *parent = 0);
49
49
50− QString getUser();
50+ QString user() const;
51 void setUser(const QString &user);
51 void setUser(const QString &user);
52− bool getDemoEdges();
52+ bool demoEdges() const;
53 void setDemoEdges(bool demoEdges);
53 void setDemoEdges(bool demoEdges);
54− bool getDemoEdgesForCurrentUser();
54+ bool demoEdgesForCurrentUser() const;
55 void setDemoEdgesForCurrentUser(bool demoEdgesForCurrentUser);
55 void setDemoEdgesForCurrentUser(bool demoEdgesForCurrentUser);
56− QString getBackgroundFile();
56+ QString backgroundFile() const;
57 void setBackgroundFile(const QString &backgroundFile);
57 void setBackgroundFile(const QString &backgroundFile);
58
58
59Q_SIGNALS:
59Q_SIGNALS:
tests/mocks/Ubuntu/DownloadDaemonListener/MockDownloadTracker.cpp+5
@@ -63,5 +63,10 @@ void MockDownloadTracker::startService()
63 if(!m_service.isEmpty() && !m_dbusPath.isEmpty()) {
63 if(!m_service.isEmpty() && !m_dbusPath.isEmpty()) {
64 m_active = true;
64 m_active = true;
65 Q_EMIT serviceReadyChanged(m_active);
65 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+ }
66 }
71 }
67}
72}
tests/mocks/Unity/fake_scope.h+2
@@ -90,6 +90,8 @@ Q_SIGNALS:
90 // signals triggered by activate(..) or preview(..) requests.
90 // signals triggered by activate(..) or preview(..) requests.
91 void previewReady(Preview *preview);
91 void previewReady(Preview *preview);
92 void activateApplication(const QString &desktop);
92 void activateApplication(const QString &desktop);
93+ void showDash();
94+ void hideDash();
93
95
94protected:
96protected:
95
97
tests/plugins/AccountsService/client.cpp+2−2
@@ -50,9 +50,9 @@ private Q_SLOTS:
50 AccountsService session;
50 AccountsService session;
51 session.setUser("testuser");
51 session.setUser("testuser");
52 session.setDemoEdges(true);
52 session.setDemoEdges(true);
53− QCOMPARE(session.getDemoEdges(), true);
53+ QCOMPARE(session.demoEdges(), true);
54 session.setDemoEdges(false);
54 session.setDemoEdges(false);
55− QCOMPARE(session.getDemoEdges(), false);
55+ QCOMPARE(session.demoEdges(), false);
56 }
56 }
57};
57};
58
58
tests/plugins/ListViewWithPageHeader/CMakeLists.txt+6
@@ -32,5 +32,11 @@ qt5_use_modules(listviewwithpageheadertestsectionExec Test Core Qml)
32target_link_libraries(listviewwithpageheadertestsectionExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
32target_link_libraries(listviewwithpageheadertestsectionExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
33add_custom_target(testlistviewwithpageheadersection ${CMAKE_CURRENT_BINARY_DIR}/listviewwithpageheadertestsectionExec -o ${CMAKE_BINARY_DIR}/testlistviewwithpageheadersection.xml,xunitxml -o -,txt)
33add_custom_target(testlistviewwithpageheadersection ${CMAKE_CURRENT_BINARY_DIR}/listviewwithpageheadertestsectionExec -o ${CMAKE_BINARY_DIR}/testlistviewwithpageheadersection.xml,xunitxml -o -,txt)
34
34
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+
35add_dependencies(qmluitests testlistviewwithpageheader)
40add_dependencies(qmluitests testlistviewwithpageheader)
36add_dependencies(qmluitests testlistviewwithpageheadersection)
41add_dependencies(qmluitests testlistviewwithpageheadersection)
42+add_dependencies(qmluitests testlistviewwithpageheadersectionexternalmodel)
tests/plugins/ListViewWithPageHeader/listviewwithpageheadertest.cpp+45
@@ -1655,6 +1655,51 @@ private Q_SLOTS:
1655 QCOMPARE(spy.count(), 0);
1655 QCOMPARE(spy.count(), 0);
1656 }
1656 }
1657
1657
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+
1658private:
1703private:
1659 QQuickView *view;
1704 QQuickView *view;
1660 ListViewWithPageHeader *lvwph;
1705 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/resultstest.cpp+1
@@ -71,6 +71,7 @@ void ResultsTest::testIconColumn_data()
71 QTest::newRow("absolute path") << "/usr/share/icons/example.png" << "/usr/share/icons/example.png";
71 QTest::newRow("absolute path") << "/usr/share/icons/example.png" << "/usr/share/icons/example.png";
72 QTest::newRow("file uri") << "file:///usr/share/icons/example.png" << "file:///usr/share/icons/example.png";
72 QTest::newRow("file uri") << "file:///usr/share/icons/example.png" << "file:///usr/share/icons/example.png";
73 QTest::newRow("http uri") << "http://images.ubuntu.com/example.jpg" << "http://images.ubuntu.com/example.jpg";
73 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";
74 QTest::newRow("themed icon") << "accessories-other" << "image://theme/accessories-other";
75 QTest::newRow("themed icon") << "accessories-other" << "image://theme/accessories-other";
75 QTest::newRow("fileicon") << ". GFileIcon http://example.org/resource.gif" << "http://example.org/resource.gif";
76 QTest::newRow("fileicon") << ". GFileIcon http://example.org/resource.gif" << "http://example.org/resource.gif";
76 QTest::newRow("themedicon") << ". GThemedIcon accessories-other accessories generic" << "image://theme/accessories-other,accessories,generic";
77 QTest::newRow("themedicon") << ". GThemedIcon accessories-other accessories generic" << "image://theme/accessories-other,accessories,generic";
tests/qmltests/CMakeLists.txt−1
@@ -14,7 +14,6 @@ set(qmltest_DEFAULT_NO_ADD_TEST FALSE)
14set(qmltest_DEFAULT_PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=minimal")
14set(qmltest_DEFAULT_PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=minimal")
15add_qml_test(Components AnimationControllerWithSignals)
15add_qml_test(Components AnimationControllerWithSignals)
16add_qml_test(Components Carousel)
16add_qml_test(Components Carousel)
17−add_qml_test(Components CrossFadeImage)
18add_qml_test(Components MathLocal)
17add_qml_test(Components MathLocal)
19add_qml_test(Components OpenEffect)
18add_qml_test(Components OpenEffect)
20add_qml_test(Components RatingStars)
19add_qml_test(Components RatingStars)
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/Dash/Apps/tst_AppPreview.qml+75−2
@@ -25,6 +25,9 @@ Item {
25 width: units.gu(60)
25 width: units.gu(60)
26 height: units.gu(80)
26 height: units.gu(80)
27
27
28+ // Fake shell
29+ QtObject { id: shell; property int height: appPreview.height }
30+
28 property var calls: []
31 property var calls: []
29
32
30 SignalSpy {
33 SignalSpy {
@@ -45,6 +48,8 @@ Item {
45 ["Unity User", 10, "10/02/2013", root.commentary],
48 ["Unity User", 10, "10/02/2013", root.commentary],
46 ]
49 ]
47 }
50 }
51+ QtObject { id: showProgress; property bool value: true }
52+ QtObject { id: progressSource; property string value: "service" }
48
53
49 QtObject {
54 QtObject {
50 id: data
55 id: data
@@ -66,8 +71,30 @@ Item {
66 ]
71 ]
67 }
72 }
68
73
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+
69 function fake_call(id, data){
96 function fake_call(id, data){
70− root.calls[root.calls.length] = id;
97+ root.calls[root.calls.length] = [id, data];
71 }
98 }
72
99
73 // The component under test
100 // The component under test
@@ -89,6 +116,10 @@ Item {
89 reviewField.focus = false;
116 reviewField.focus = false;
90 reviewField.text = "";
117 reviewField.text = "";
91 data.rating = rating.value;
118 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;
92 }
123 }
93
124
94 function test_actions() {
125 function test_actions() {
@@ -102,7 +133,7 @@ Item {
102
133
103 var actions = data.actions;
134 var actions = data.actions;
104 for(var i = 0; i < actions.length; i++) {
135 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.");
106 }
137 }
107 }
138 }
108
139
@@ -124,6 +155,7 @@ Item {
124
155
125 function test_review_focus() {
156 function test_review_focus() {
126 var appReviews = findChild(appPreview, "appReviews");
157 var appReviews = findChild(appPreview, "appReviews");
158+ appReviews.visible = true;
127 var sendButton = findChild(appReviews, "sendButton");
159 var sendButton = findChild(appReviews, "sendButton");
128 var reviewField = findChild(appReviews, "reviewField");
160 var reviewField = findChild(appReviews, "reviewField");
129
161
@@ -162,5 +194,46 @@ Item {
162 verify(buttons.visible == true);
194 verify(buttons.visible == true);
163 }
195 }
164
196
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+
165 }
238 }
166}
239}
tests/qmltests/Dash/tst_GenericScopeView.qml+14
@@ -52,6 +52,20 @@ Item {
52 tryCompare(pageHeader, "searchQuery", "")
52 tryCompare(pageHeader, "searchQuery", "")
53 tryCompare(genericScopeView, "previewShown", false);
53 tryCompare(genericScopeView, "previewShown", false);
54 }
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);
68+ }
55 }
69 }
56 }
70 }
57}
71}