on xenial help sign in
First cut at porting phablet code to the new scopes API.

Approved by Ricardo Salveti, Michał Sawicz, PS Jenkins bot, Michael Zanetti.

commit8cbde4bd050239ac16b3ed6966bc9625530297e1 authorPawel Stolowski <pawel.stolowski@canonical.com> dateWed 19 Jun 2013, 23:12 (13 years ago) parenta467fa8859dfd9
82 files changed+913−3448
Components/IconUtil.js+42 Dash/Apps/ApplicationsFilterGrid.qml+2−2 Dash/Dash.qml+20−20 Dash/DashApps.qml+5−5 Dash/DashBar.qml+3−8 Dash/DashContent.qml+18−17 Dash/DashHome.qml+13−35 Dash/DashMusic.qml+7−7 Dash/DashPeople.qml−235 Dash/DashVideos.qml+9−9 Dash/GenericLensView.qml → Dash/GenericScopeView.qml+8−7 Dash/Music/MusicFilterGrid.qml+2−2 Dash/People/CarouselDelegatePeople.qml−166 Dash/People/Data.qml−71 Dash/People/Delegate.qml−167 Dash/People/PeopleCarousel.qml−43 Dash/People/PeopleFilterGrid.qml−74 Dash/People/PeoplePreview.qml−124 Dash/People/Preview/Address.qml−74 Dash/People/Preview/Base.qml−22 Dash/People/Preview/Generic.qml−80 Dash/People/Preview/Phone.qml−108 Dash/People/Preview/Status.qml−97 Dash/People/graphics/bottomshape@18.png Dash/People/graphics/bottomshape@18.sci−5 Dash/People/graphics/icon_facebook@18.png Dash/People/graphics/icon_offline@18.png Dash/People/graphics/icon_online@18.png Dash/People/graphics/icon_twitter@18.png Dash/People/graphics/icon_unknown@18.png Dash/People/graphics/icon_write_text@18.png Dash/People/graphics/star_favourite@18.png Dash/People/graphics/star_not_favourite@18.png Dash/LensDelegateMapper.qml → Dash/ScopeDelegateMapper.qml+10−11 Dash/LensView.qml → Dash/ScopeView.qml+4−4 Dash/Video/VideosFilterGrid.qml+2−2 Dash/graphics/lensIcons/Applications@18.png Dash/graphics/lensIcons/Home@18.png Dash/graphics/lensIcons/Music@18.png Dash/graphics/lensIcons/People@18.png Dash/graphics/lensIcons/Videos@18.png Shell.qml+3−3 build_unity+5−15 debian/changelog+6 debian/control+3−1 plugins/Unity/CMakeLists.txt+2−3 plugins/Unity/categories.cpp+4−54 plugins/Unity/categories.h+1−11 plugins/Unity/lens.cpp−338 plugins/Unity/lenses.cpp−182 plugins/Unity/peoplepreviewdata.cpp−438 plugins/Unity/peoplepreviewdata.h−251 plugins/Unity/plugin.cpp+4−9 plugins/Unity/scope.cpp+273 plugins/Unity/lens.h → plugins/Unity/scope.h+16−44 plugins/Unity/scopes.cpp+176 plugins/Unity/lenses.h → plugins/Unity/scopes.h+25−21 po/unity8.pot+9−36 tests/autopilot/unity8/tests/helpers.py+1−1 tests/autopilot/unity8/tests/testhud.py+1−1 tests/autopilot/unity8/tests/testlockscreen.py+1−1 tests/qmltests/CMakeLists.txt+2−4 tests/qmltests/Dash/People/tst_PeopleFilterGrid.qml−154 tests/qmltests/Dash/qml/FakeLensView.qml → tests/qmltests/Dash/qml/FakeScopeView.qml+9−9 tests/qmltests/Dash/qml/fake_generic_lensView.qml → tests/qmltests/Dash/qml/fake_generic_scopeView.qml+3−3 tests/qmltests/Dash/qml/fake_lensView1.qml → tests/qmltests/Dash/qml/fake_scopeView1.qml+3−3 tests/qmltests/Dash/qml/fake_lensView2.qml → tests/qmltests/Dash/qml/fake_scopeView2.qml+3−3 tests/qmltests/Dash/qml/fake_lensView3.qml → tests/qmltests/Dash/qml/fake_scopeView3.qml+3−3 tests/qmltests/Dash/qml/fake_lensView4.qml → tests/qmltests/Dash/qml/fake_scopeView4.qml+3−3 tests/qmltests/Dash/tst_Dash.qml+34−34 tests/qmltests/Dash/tst_DashBar.qml+4−4 tests/qmltests/Dash/tst_DashContent.qml+75−72 tests/qmltests/Dash/tst_FilterGrids.qml−1 tests/qmltests/Dash/tst_GenericLensView.qml → tests/qmltests/Dash/tst_GenericScopeView.qml+10−10 tests/qmltests/Dash/tst_PeoplePreview.qml−254 tests/qmltests/Dash/tst_LensView.qml → tests/qmltests/Dash/tst_ScopeView.qml+12−12 tests/qmltests/plugins/Unity/CMakeLists.txt+2−2 tests/qmltests/plugins/Unity/fake_lens.cpp → tests/qmltests/plugins/Unity/fake_scope.cpp+15−13 tests/qmltests/plugins/Unity/fake_lens.h → tests/qmltests/plugins/Unity/fake_scope.h+6−6 tests/qmltests/plugins/Unity/fake_lenses.cpp → tests/qmltests/plugins/Unity/fake_scopes.cpp+38−38 tests/qmltests/plugins/Unity/fake_lenses.h → tests/qmltests/plugins/Unity/fake_scopes.h+13−13 tests/qmltests/plugins/Unity/fake_unity_plugin.cpp+3−3
Components/IconUtil.jsnew file+42
@@ -0,0 +1,42 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+.pragma library
18+
19+// FIXME: a quick hack to get icons out of gicons and fallback to
20+// base icon for annotated icons. Doesn't correctly handle all icons.
21+// Proper global solution needed.
22+function from_gicon(name) {
23+ var icon_name = name;
24+ var annotated_re = /^. UnityProtocolAnnotatedIcon/;
25+ if (annotated_re.test(name)) {
26+ var base_icon_re = /'base-icon':.+?'(.+?)'/;
27+ var base_icon = name.toString().match(base_icon_re);
28+ icon_name = base_icon[1];
29+ }
30+ else {
31+ var themed_re = /^. GThemedIcon\s*([^\s]+)\s*/;
32+ var themed = name.match(themed_re);
33+ if (themed) {
34+ return "image://gicon/" + themed[1];
35+ }
36+ }
37+ var remote_re = /^http/;
38+ if (remote_re.test(icon_name)) {
39+ return icon_name;
40+ }
41+ return "image://gicon/" + icon_name;
42+}
Dash/Apps/ApplicationsFilterGrid.qml+2−2
@@ -35,7 +35,7 @@ FilterGrid {
3535 objectName: "delegate" + index
3636 Application {
3737 id: application
38− desktopFile: model.column_6 ? stripProtocol(model.column_6) : model.desktopFile // FIXME: this is temporary
38+ desktopFile: model.column_7 ? stripProtocol(model.column_7) : model.desktopFile // FIXME: this is temporary
3939
4040 function stripProtocol(uri) {
4141 var chunks = uri.split('file://')
@@ -47,7 +47,7 @@ FilterGrid {
4747
4848 width: filterGrid.cellWidth
4949 height: filterGrid.cellHeight
50− text: model.column_4 ? model.column_4 : application.name // FIXME: this is temporary
50+ text: model.column_5 ? model.column_5 : application.name // FIXME: this is temporary
5151 imageWidth: units.gu(8)
5252 imageHeight: units.gu(7.5)
5353 source: icon.indexOf("/") == -1 ? "image://gicon/" + icon : icon
Dash/Dash.qml+20−20
@@ -24,36 +24,36 @@ Showable {
2424 id: dash
2525
2626 property alias contentProgress: dashContent.contentProgress
27− property string showLensOnLoaded: "home.lens"
27+ property string showScopeOnLoaded: "home.scope"
2828 property real contentScale: 1.0
2929
3030 width: units.gu(40)
3131 height: units.gu(71)
3232
33− function setCurrentLens(lensId, animate, reset) {
34− var lensIndex = filteredLenses.findFirst(Lenses.RoleId, lensId)
33+ function setCurrentScope(scopeId, animate, reset) {
34+ var scopeIndex = filteredScopes.findFirst(Scopes.RoleId, scopeId)
3535
36− if (lensIndex == -1) {
37− console.warn("No match for lens with id: %1".arg(lensId))
36+ if (scopeIndex == -1) {
37+ console.warn("No match for scope with id: %1".arg(scopeId))
3838 return
3939 }
4040
41− if (lensIndex == dashContent.currentIndex && !reset) {
42− // the lens is already the current one
41+ if (scopeIndex == dashContent.currentIndex && !reset) {
42+ // the scope is already the current one
4343 return
4444 }
4545
46− dashContent.setCurrentLensAtIndex(lensIndex, animate, reset)
46+ dashContent.setCurrentScopeAtIndex(scopeIndex, animate, reset)
4747 }
4848
4949 SortFilterProxyModel {
50− id: filteredLenses
51− model: Lenses {
52− id: lenses
50+ id: filteredScopes
51+ model: Scopes {
52+ id: scopes
5353 }
5454 dynamicSortFilter: true
5555
56− filterRole: Lenses.RoleVisible
56+ filterRole: Scopes.RoleVisible
5757 filterRegExp: RegExp("^true$")
5858 }
5959
@@ -61,17 +61,17 @@ Showable {
6161 id: dashContent
6262 objectName: "dashContent"
6363 anchors.fill: parent
64− model: filteredLenses
65− lenses: lenses
64+ model: filteredScopes
65+ scopes: scopes
6666 onMovementStarted: dashbar.startNavigation()
6767 onMovementEnded: dashbar.stopNavigation()
6868 onContentFlickStarted: dashbar.finishNavigation()
6969 onContentEndReached: dashbar.finishNavigation()
7070 onPreviewShown: dashbar.finishNavigation()
71− onLensLoaded: {
72− if (lensId == dash.showLensOnLoaded) {
73− dash.setCurrentLens(lensId, false, false)
74− dash.showLensOnLoaded = ""
71+ onScopeLoaded: {
72+ if (scopeId == dash.showScopeOnLoaded) {
73+ dash.setCurrentScope(scopeId, false, false)
74+ dash.showScopeOnLoaded = ""
7575 }
7676 }
7777 scale: dash.contentScale
@@ -84,9 +84,9 @@ Showable {
8484 anchors.bottom: parent.bottom
8585 anchors.left: parent.left
8686 anchors.right: parent.right
87− model: filteredLenses
87+ model: filteredScopes
8888 currentIndex: dashContent.currentIndex
89− onItemSelected: dashContent.setCurrentLensAtIndex(index, true, false)
89+ onItemSelected: dashContent.setCurrentScopeAtIndex(index, true, false)
9090 opacity: dash.contentScale == 1.0 ? 1.0 : 0.0
9191 Behavior on opacity { NumberAnimation { easing.type: Easing.OutQuad; duration: 150 } }
9292 }
Dash/DashApps.qml+5−5
@@ -21,8 +21,8 @@ import "../Components"
2121import "../Components/ListItems"
2222import "Apps"
2323
24−LensView {
25− id: lensView
24+ScopeView {
25+ id: scopeView
2626
2727 // FIXME: a way to aggregate these models would be ideal
2828 property var mainStageApplicationsModel: shell.applicationManager.mainStageApplications
@@ -40,7 +40,7 @@ LensView {
4040 }
4141
4242 Binding {
43− target: lensView.lens
43+ target: scopeView.scope
4444 property: "searchQuery"
4545 value: pageHeader.searchQuery
4646 }
@@ -86,7 +86,7 @@ LensView {
8686 dynamicSortFilter: true
8787 filterRole: 2 // this is the category id for each result
8888 filterRegExp: /^3$/ // only proxy items that are category 3 - Installed
89− model: dashContent.lenses.get("applications.lens").results
89+ model: dashContent.scopes.get("applications.scope").results
9090 }
9191
9292 property var categoryModels: {
@@ -177,7 +177,7 @@ LensView {
177177 width: categoryView.width
178178 text: i18n.tr("Apps")
179179 searchEntryEnabled: true
180− searchHistory: lensView.searchHistory
180+ searchHistory: scopeView.searchHistory
181181 }
182182 }
183183}
Dash/DashBar.qml+3−8
@@ -26,7 +26,7 @@ Item {
2626
2727 property int lineHeight: units.dp(2)
2828 property int itemSize: units.gu(7)
29− property int iconSize: units.gu(2.5)
29+ property int iconSize: units.gu(3.5)
3030
3131 signal itemSelected(int index)
3232
@@ -97,14 +97,9 @@ Item {
9797
9898 Image {
9999 anchors.centerIn: parent
100− /* FIXME: should be 'source: lens.iconHint' but the
101− lenses do not contain the right icons yet
102− */
103− source: "graphics/lensIcons/%1.png".arg(lens.name)
104− height: iconSize
105− width: iconSize
100+ source: scope.iconHint
101+ sourceSize { width: iconSize; height: iconSize }
106102 // opacity: index == currentIndex ? 1 : 1 // same opacity for now
107− smooth: true
108103 }
109104 }
110105 }
Dash/DashContent.qml+18−17
@@ -24,34 +24,34 @@ Item {
2424 height: units.gu(71)
2525
2626 property var model: null
27− property var lenses: null
27+ property var scopes: null
2828 property real contentProgress: Math.max(0, Math.min(dashContentList.contentX / (dashContentList.contentWidth - dashContentList.width), units.dp(1)))
2929 property alias currentIndex: dashContentList.currentIndex
3030
31− property LensDelegateMapper lensMapper : LensDelegateMapper {}
31+ property ScopeDelegateMapper scopeMapper : ScopeDelegateMapper {}
3232
3333 signal movementStarted()
3434 signal movementEnded()
3535 signal contentFlickStarted()
3636 signal contentEndReached()
3737 signal previewShown()
38− signal lensLoaded(string lensId)
38+ signal scopeLoaded(string scopeId)
3939 signal positionedAtBeginning()
4040
41− // If we set the current lens index before the lenses have been added,
42− // then we need to wait until the loaded signals gets emitted from the lenses
41+ // If we set the current scope index before the scopes have been added,
42+ // then we need to wait until the loaded signals gets emitted from the scopes
4343 property var set_current_index: undefined
4444 Connections {
45− target: lenses
45+ target: scopes
4646 onLoadedChanged: {
47− if (lenses.loaded && set_current_index != undefined) {
48− setCurrentLensAtIndex(set_current_index[0], set_current_index[1], set_current_index[2]);
47+ if (scopes.loaded && set_current_index != undefined) {
48+ setCurrentScopeAtIndex(set_current_index[0], set_current_index[1], set_current_index[2]);
4949 set_current_index = undefined;
5050 }
5151 }
5252 }
5353
54− function setCurrentLensAtIndex(index, animate, reset) {
54+ function setCurrentScopeAtIndex(index, animate, reset) {
5555 var storedMoveDuration = dashContentList.highlightMoveDuration
5656 var storedMoveSpeed = dashContentList.highlightMoveVelocity
5757 if (!animate) {
@@ -59,8 +59,8 @@ Item {
5959 dashContentList.highlightMoveDuration = 0
6060 }
6161
62− // if the lenses haven't loaded yet, then wait until they are.
63− if (!lenses.loaded) {
62+ // if the scopes haven't loaded yet, then wait until they are.
63+ if (!scopes.loaded) {
6464 set_current_index = [ index, animate, reset ]
6565 return;
6666 }
@@ -85,7 +85,7 @@ Item {
8585 id: dashContentList
8686 objectName: "dashContentList"
8787
88− interactive: dashContent.lenses.loaded
88+ interactive: dashContent.scopes.loaded
8989
9090 anchors.fill: parent
9191 model: dashContent.model
@@ -97,7 +97,7 @@ Item {
9797 highlightMoveDuration: 250
9898 highlightRangeMode: ListView.StrictlyEnforceRange
9999 /* FIXME: workaround rendering issue due to use of ShaderEffectSource in
100− UbuntuShape. While switching from the home lens to the People lens the
100+ UbuntuShape. While switching from the home scope to the People scope the
101101 rendering would block midway.
102102 */
103103 cacheBuffer: 2147483647
@@ -107,7 +107,7 @@ Item {
107107 // If the number of items is less than the current index, then need to reset to another item.
108108 onCountChanged: {
109109 if (currentIndex >= count)
110− dashContent.setCurrentLensAtIndex(count-1, true, true)
110+ dashContent.setCurrentScopeAtIndex(count-1, true, true)
111111 }
112112
113113 delegate:
@@ -115,14 +115,15 @@ Item {
115115 width: ListView.view.width
116116 height: ListView.view.height
117117 asynchronous: true
118− source: lensMapper.map(lens.id)
118+ source: scopeMapper.map(scope.id)
119+
119120 onLoaded: {
120− item.lens = Qt.binding(function() { return lens })
121+ item.scope = Qt.binding(function() { return scope })
121122 item.isCurrent = Qt.binding(function() { return ListView.isCurrentItem })
122123 item.searchHistory = Qt.binding(function() { return shell.searchHistory })
123124 dashContentList.movementStarted.connect(item.movementStarted)
124125 dashContent.positionedAtBeginning.connect(item.positionedAtBeginning)
125− dashContent.lensLoaded(item.lens.id)
126+ dashContent.scopeLoaded(item.scope.id)
126127 }
127128 Connections {
128129 target: item
Dash/DashHome.qml+13−35
@@ -23,9 +23,8 @@ import "../Applications"
2323import "Apps"
2424import "Video"
2525import "Music"
26−import "People"
2726
28−LensView {
27+ScopeView {
2928 id: root
3029
3130 onMovementStarted: listView.showHeader()
@@ -34,20 +33,12 @@ LensView {
3433 id: categoryListModel
3534 // specifies page's content categories, type of delegate and model used in each category
3635 ListElement { category: "Frequent Apps"; component: "AppsGrid"; modelName: "AppsModel" }
37− ListElement { category: "Favourite People"; component: "PeopleCarousel"; modelName: "FavouriteModel" }
38− ListElement { category: "People Recently in Touch"; component: "PeopleGrid"; modelName: "RecentModel" }
3936 ListElement { category: "Recent Music"; component: "MusicGrid"; modelName: "MusicModel" }
4037 ListElement { category: "Videos Popular Online"; component: "VideosGrid"; modelName: "VideosModel" }
4138 function getCategory(category1) {
4239 if (category1 === "Frequent Apps") {
4340 return i18n.tr("Frequent Apps");
4441 }
45− if (category1 === "Favourite People") {
46− return i18n.tr("Favourite People");
47− }
48− if (category1 === "People Recently in Touch") {
49− return i18n.tr("People Recently in Touch");
50− }
5142 if (category1 === "Recent Music") {
5243 return i18n.tr("Recent Music");
5344 }
@@ -90,33 +81,24 @@ LensView {
9081 }
9182
9283 Component.onCompleted: {
93− var lens = dashContent.lenses.get("people.lens")
94− if (lens) {
95− favouritesFilter.model = dashContent.lenses.get("people.lens").results
96− recentFilter.model = dashContent.lenses.get("people.lens").results
84+ var scope = dashContent.scopes.get("mockmusicmaster.scope")
85+ if (scope) {
86+ musicFilter.model = dashContent.scopes.get("mockmusicmaster.scope").results
9787 }
98− lens = dashContent.lenses.get("mockmusic.lens")
99− if (lens) {
100− musicFilter.model = dashContent.lenses.get("mockmusic.lens").results
101− }
102− lens = dashContent.lenses.get("mockvideos.lens")
103− if (lens) {
104− videosFilter.model = dashContent.lenses.get("mockvideos.lens").results
88+ scope = dashContent.scopes.get("mockvideosmaster.scope")
89+ if (scope) {
90+ videosFilter.model = dashContent.scopes.get("mockvideosmaster.scope").results
10591 }
10692 }
10793
10894 Connections {
10995 target: dashContent
110− onLensLoaded: switch (lensId) {
111− case "people.lens":
112− favouritesFilter.model = dashContent.lenses.get("people.lens").results
113− recentFilter.model = dashContent.lenses.get("people.lens").results
114− break;
115− case "mockmusic.lens":
116− musicFilter.model = dashContent.lenses.get("mockmusic.lens").results
96+ onScopeLoaded: switch (scopeId) {
97+ case "mockmusicmaster.scope":
98+ musicFilter.model = dashContent.scopes.get("mockmusicmaster.scope").results
11799 break;
118− case "mockvideos.lens":
119− videosFilter.model = dashContent.lenses.get("mockvideos.lens").results
100+ case "mockvideosmaster.scope":
101+ videosFilter.model = dashContent.scopes.get("mockvideosmaster.scope").results
120102 break;
121103 }
122104 }
@@ -140,14 +122,10 @@ LensView {
140122 }
141123 }
142124
143− Component { id: peopleCarousel; PeopleCarousel {} }
144− Component { id: peopleGrid; PeopleFilterGrid {} }
145125 Component { id: musicGrid; MusicFilterGrid {} }
146126 Component { id: videosGrid; VideosFilterGrid {} }
147127 property var componentModels: {
148128 "AppsGrid": applicationsFilterGrid,
149− "PeopleCarousel": peopleCarousel,
150− "PeopleGrid": peopleGrid,
151129 "MusicGrid": musicGrid,
152130 "VideosGrid": videosGrid,
153131 }
@@ -171,7 +149,7 @@ LensView {
171149 onLoaded: {
172150 item.model = categoryModels[modelName]
173151
174− //FIXME: workaround for lack of previews for videos in Home lens.
152+ //FIXME: workaround for lack of previews for videos in Home scope.
175153 //Need to connect to the clicked() signal here and act upon it here instead.
176154 if (component === "VideosGrid") {
177155 function playVideo(index, data) {
Dash/DashMusic.qml+7−7
@@ -20,8 +20,8 @@ import "../Components"
2020import "../Components/ListItems" as ListItems
2121import "Music"
2222
23−LensView {
24− id: lensView
23+ScopeView {
24+ id: scopeView
2525
2626 property var categoryNames: [
2727 i18n.tr("Featured"),
@@ -37,7 +37,7 @@ LensView {
3737 onMovementStarted: categoryView.showHeader()
3838
3939 Binding {
40− target: lensView.lens
40+ target: scopeView.scope
4141 property: "searchQuery"
4242 value: pageHeader.searchQuery
4343 }
@@ -59,7 +59,7 @@ LensView {
5959
6060 function getRenderer(categoryId) {
6161 switch (categoryId) {
62− case 0: return musicCarousel
62+ case 1: return musicCarousel
6363 default: return musicFilterGrid
6464 }
6565 }
@@ -67,7 +67,7 @@ LensView {
6767 ListViewWithPageHeader {
6868 id: categoryView
6969 anchors.fill: parent
70− model: lensView.categories
70+ model: scopeView.categories
7171
7272 onAtYEndChanged: if (atYEnd) endReached()
7373 onMovingChanged: if (moving && atYEnd) endReached()
@@ -80,7 +80,7 @@ LensView {
8080
8181 Loader {
8282 anchors { top: parent.top; left: parent.left; right: parent.right }
83− sourceComponent: lensView.getRenderer(base.categoryId)
83+ sourceComponent: scopeView.getRenderer(base.categoryId)
8484 onLoaded: {
8585 item.model = results
8686 }
@@ -98,7 +98,7 @@ LensView {
9898 width: categoryView.width
9999 text: i18n.tr("Music")
100100 searchEntryEnabled: true
101− searchHistory: lensView.searchHistory
101+ searchHistory: scopeView.searchHistory
102102 }
103103 }
104104}
Dash/DashPeople.qmldeleted−235
@@ -1,235 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
19−import Dee 3.0
20−import Unity 0.1
21−import Utils 0.1
22−import "../Components"
23−import "../Components/ListItems" as ListItems
24−import "People"
25−
26−LensView {
27− id: lensView
28− property alias previewShown: previewLoader.onScreen
29−
30− property var categoryNames: [
31− i18n.tr("Favourites"),
32− i18n.tr("Recently in touch"),
33− i18n.tr("New Contacts"),
34− i18n.tr("A-Z")
35− ]
36−
37− onIsCurrentChanged: {
38− pageHeader.resetSearch();
39− }
40−
41− onMovementStarted: categoryView.showHeader()
42−
43− Binding {
44− target: lensView.lens
45− property: "searchQuery"
46− value: pageHeader.searchQuery
47− }
48−
49− Connections {
50− target: panel
51− onSearchClicked: if (isCurrent) {
52− pageHeader.triggerSearch()
53− categoryView.showHeader()
54− }
55− }
56−
57− OpenEffect {
58− id: effect
59− anchors {
60− fill: parent
61− bottomMargin: -bottomOverflow
62− }
63− sourceItem: categoryView
64−
65− enabled: gap > 0.0
66−
67− topGapPx: (1 - gap) * positionPx
68− topOpacity: (1 - gap * 1.2)
69− bottomGapPx: positionPx + gap * (targetBottomGapPx - positionPx)
70− bottomOverflow: units.gu(20)
71− bottomOpacity: 1 - (gap * 0.8)
72−
73− property int targetBottomGapPx: height - units.gu(8) - bottomOverflow
74− property real gap: previewLoader.open ? 1.0 : 0.0
75−
76− Behavior on gap {
77− NumberAnimation {
78− duration: 200
79− easing.type: Easing.InOutQuad
80− onRunningChanged: {
81− if (!previewLoader.open && !running) {
82− previewLoader.onScreen = false;
83− }
84− }
85− }
86− }
87− }
88−
89− ListViewWithPageHeader {
90− id: categoryView
91− anchors.fill: parent
92− model: lensView.categories
93− onAtYEndChanged: if (atYEnd) endReached()
94− onMovingChanged: if (moving && atYEnd) endReached()
95− clipListView: !previewLoader.onScreen
96−
97− delegate: ListItems.Base {
98− id: base
99− property int categoryIndex: index
100− property int categoryId: id
101− highlightWhenPressed: false
102−
103− Loader {
104− width: categoryView.width
105− sourceComponent: base.categoryId == 0 ? peopleCarouselComponent : peopleGridComponent
106−
107− onLoaded: {
108− item.categoryId = Qt.binding(function() { return base.categoryId; })
109− item.categoryIndex = Qt.binding(function() { return base.categoryIndex; })
110− item.model = results;
111− }
112− }
113− }
114−
115− sectionProperty: "name"
116− sectionDelegate: ListItems.Header {
117− width: categoryView.width
118− text: i18n.tr(section)
119− }
120− pageHeader: PageHeader {
121− id: pageHeader
122− width: categoryView.width
123− text: i18n.tr("People")
124− searchEntryEnabled: true
125− searchHistory: lensView.searchHistory
126− }
127− }
128−
129− Component {
130− id: peopleCarouselComponent
131− PeopleCarousel {
132− id: peopleCarousel
133−
134− property int categoryId
135− property int categoryIndex
136−
137− onClicked: {
138− effect.positionPx = mapToItem(categoryView, 0, itemY).y;
139− previewData.model = delegateItem.dataModel;
140− previewData.uri = delegateItem.dataModel.uri;
141− previewLoader.open = true;
142− }
143− }
144− }
145−
146− Component {
147− id: peopleGridComponent
148− PeopleFilterGrid {
149− id: peopleGrid
150−
151− property int categoryIndex
152−
153− onClicked: {
154− if (peopleGrid.columnCount == 1) {
155− if (categoryIndex >= categoryView.model.count -1 && index >= peopleGrid.model.count - 1) {
156− effect.positionPx = mapToItem(categoryView, 0, itemY).y;
157− } else {
158− effect.positionPx = mapToItem(categoryView, 0, itemY + peopleGrid.cellHeight).y
159− }
160− } else {
161− effect.positionPx = mapToItem(categoryView, 0, itemY).y
162− }
163− previewData.model = data;
164− previewData.uri = data.uri
165− previewLoader.open = true;
166− }
167− }
168− }
169−
170− Loader {
171− id: previewLoader
172− height: effect.bottomGapPx - effect.topGapPx
173− anchors {
174− top: parent.top
175− topMargin: effect.topGapPx
176− left: parent.left
177− right: parent.right
178− }
179− sourceComponent: onScreen ? previewComponent : undefined
180−
181− property bool open: false
182− property bool onScreen: false
183− property QtObject videoItem
184−
185− onOpenChanged: {
186− if (open) {
187− onScreen = true
188− }
189− }
190−
191− onLoaded: {
192− if (previewData.ready) {
193− item.model = previewData;
194− }
195− }
196− }
197−
198− Component {
199− id: previewComponent
200−
201− PeoplePreview {
202− id: preview
203− anchors.fill: parent
204− forceSquare: true
205− onClose: {
206− open = false;
207− }
208− }
209− }
210−
211− PeoplePreviewData {
212− id: previewData
213− lens: lensView.lens
214− property Data model
215−
216− onError: previewLoader.open = false
217− onReadyChanged: {
218− if (previewLoader.item) {
219− previewLoader.item.model = ready ? previewData : undefined
220− }
221− }
222− }
223−
224− // TODO: Move as InverseMouseArea to DashPreview
225− MouseArea {
226− enabled: previewLoader.onScreen
227− anchors {
228− fill: parent
229− topMargin: effect.bottomGapPx
230− }
231− onClicked: {
232− previewLoader.open = false;
233− }
234− }
235−}
Dash/DashVideos.qml+9−9
@@ -20,8 +20,8 @@ import "../Components"
2020import "../Components/ListItems" as ListItems
2121import "Video"
2222
23−LensView {
24− id: lensView
23+ScopeView {
24+ id: scopeView
2525 property alias previewShown: previewLoader.onScreen
2626
2727 property var categoryNames: [
@@ -38,7 +38,7 @@ LensView {
3838 onMovementStarted: categoryView.showHeader()
3939
4040 Binding {
41− target: lensView.lens
41+ target: scopeView.scope
4242 property: "searchQuery"
4343 value: pageHeader.searchQuery
4444 }
@@ -60,7 +60,7 @@ LensView {
6060
6161 function getRenderer(categoryId) {
6262 switch (categoryId) {
63− case 0: return videosCarousel
63+ case 1: return videosCarousel
6464 default: return videosFilterGrid
6565 }
6666 }
@@ -100,7 +100,7 @@ LensView {
100100 ListViewWithPageHeader {
101101 id: categoryView
102102 anchors.fill: parent
103− model: lensView.categories
103+ model: scopeView.categories
104104 clipListView: !previewLoader.onScreen
105105
106106 onAtYEndChanged: if (atYEnd) endReached()
@@ -115,7 +115,7 @@ LensView {
115115 Loader {
116116 id: loader
117117 anchors { top: parent.top; left: parent.left; right: parent.right }
118− sourceComponent: lensView.getRenderer(base.categoryId)
118+ sourceComponent: scopeView.getRenderer(base.categoryId)
119119 onLoaded: {
120120 item.model = results
121121 }
@@ -127,9 +127,9 @@ LensView {
127127 var dataItem;
128128 // VideosCarousel and VideosFilterGrid have different
129129 // clicked signals, accomodate for that
130− if (categoryId == 0) {
130+ if (categoryId == 1) {
131131 var fileUri = delegateItem.model.column_0.replace(/^[^:]+:/, "")
132− dataItem = {fileUri: fileUri, nfoUri: delegateItem.model.column_5}
132+ dataItem = {fileUri: fileUri, nfoUri: delegateItem.model.column_6}
133133 } else {
134134 dataItem = data;
135135 }
@@ -154,7 +154,7 @@ LensView {
154154 width: categoryView.width
155155 text: i18n.tr("Videos")
156156 searchEntryEnabled: true
157− searchHistory: lensView.searchHistory
157+ searchHistory: scopeView.searchHistory
158158 }
159159 }
160160
Dash/GenericLensView.qml → Dash/GenericScopeView.qmlrenamed+8−7
@@ -18,9 +18,10 @@ import QtQuick 2.0
1818import Ubuntu.Components 0.1
1919import "../Components"
2020import "../Components/ListItems" as ListItems
21+import "../Components/IconUtil.js" as IconUtil
2122
22−LensView {
23− id: lensView
23+ScopeView {
24+ id: scopeView
2425
2526 onIsCurrentChanged: {
2627 pageHeader.resetSearch();
@@ -29,7 +30,7 @@ LensView {
2930 onMovementStarted: categoryView.showHeader()
3031
3132 Binding {
32− target: lensView.lens
33+ target: scopeView.scope
3334 property: "searchQuery"
3435 value: pageHeader.searchQuery
3536 }
@@ -45,7 +46,7 @@ LensView {
4546 ListViewWithPageHeader {
4647 id: categoryView
4748 anchors.fill: parent
48− model: lensView.categories
49+ model: scopeView.categories
4950 onAtYEndChanged: if (atYEnd) endReached()
5051 onMovingChanged: if (moving && atYEnd) endReached()
5152
@@ -71,10 +72,10 @@ LensView {
7172 delegate: Tile {
7273 width: filtergrid.cellWidth
7374 height: filtergrid.cellHeight
74− text: column_4 ? column_4 : "" // FIXME: this shouldn't be necessary
75+ text: column_5 ? column_5 : "" // FIXME: this shouldn't be necessary
7576 imageWidth: units.gu(11)
7677 imageHeight: units.gu(16)
77− source: column_1 ? column_1 : "" // FIXME: ditto
78+ source: column_1 ? IconUtil.from_gicon(column_1) : "" // FIXME: ditto
7879 }
7980 }
8081 }
@@ -88,7 +89,7 @@ LensView {
8889 id: pageHeader
8990 objectName: "pageHeader"
9091 width: categoryView.width
91− text: lensView.lens.name
92+ text: scopeView.scope.name
9293 searchEntryEnabled: true
9394 }
9495 }
Dash/Music/MusicFilterGrid.qml+2−2
@@ -38,8 +38,8 @@ FilterGrid {
3838 height: filterGrid.cellHeight
3939 iconWidth: filterGrid.iconWidth
4040 iconHeight: filterGrid.iconHeight
41− artist: model.column_4
42− album: model.column_5
41+ artist: model.column_5
42+ album: model.column_6
4343 source: model.column_1
4444 onClicked: {
4545 filterGrid.clicked(index);
Dash/People/CarouselDelegatePeople.qmldeleted−166
@@ -1,166 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
19−import "../../Components"
20−
21−BaseCarouselDelegate {
22− id: item
23−
24− property var dataModel
25− readonly property real frameHeight: Math.max(height / 3.6, units.gu(5.5))
26−
27− UbuntuShape {
28− anchors.fill: parent
29− radius: "medium"
30− borderSource: ""
31− image: Image {
32− asynchronous: true
33− sourceSize { width: item.width; height: item.height }
34− source: dataModel.avatar ? dataModel.avatar : ""
35− fillMode: Image.PreserveAspectCrop
36− }
37− }
38−
39− Component {
40− id: component_frame
41− Item {
42− id: frame
43−
44− BorderImage {
45− // TODO This will go away once we have 'clip: true' in UbuntuShape
46− anchors.centerIn: parent
47− width: parent.width + units.gu(1.5)
48− height: parent.height + units.gu(1.5)
49− visible: labelRemotePost.visible
50− opacity: 0.9
51− source: "graphics/bottomshape.sci"
52− }
53−
54− property bool showRemoteDetails: true
55− // To decide if the remote icon and time should be shown, its once layed out to do so.
56− // Then it's checked if everything fits in the frame size. If not, showRemoteDetails is set false
57− // Using bindings to do so cause a binding loop
58− function checkSizeForRemoteDetails() {
59− showRemoteDetails = true
60− showRemoteDetails = (frame.height - column.minimumHeight) >= labelRemotePostTime.height
61− }
62−
63− Item {
64− id: remoteSourceIconContainer
65−
66− // TODO use proper asset and get rid of these dimensions
67− width: units.gu(3)
68− height: units.gu(4)
69− visible: showRemoteDetails
70−
71− Image {
72− anchors.centerIn: parent
73− anchors.horizontalCenterOffset: units.gu(1)
74− source: dataModel.remoteSourceIcon ? dataModel.remoteSourceIcon : ""
75− fillMode: Image.PreserveAspectFit
76− }
77− }
78−
79− Column {
80− id: column
81−
82− property real minimumHeight: labelName.height + labelRemotePost.height + anchors.topMargin + anchors.bottomMargin
83−
84− anchors {
85− left: remoteSourceIconContainer.visible ? remoteSourceIconContainer.right : parent.left
86− right: parent.right
87− top: remoteSourceIconContainer.visible ? parent.top : undefined
88− verticalCenter: remoteSourceIconContainer.visible ? undefined : parent.verticalCenter
89− margins: units.gu(1)
90− }
91−
92− Label {
93− id: labelName
94−
95− width: parent.width
96− text: dataModel.name ? dataModel.name : ""
97− color: "white"
98− fontSize: "x-small"
99− elide: Text.ElideRight
100− font.weight: Font.Bold
101− onTextChanged: checkSizeForRemoteDetails()
102− }
103−
104− Label {
105− id: labelRemotePost
106−
107− width: parent.width
108− text: dataModel.remotePost ? dataModel.remotePost : ""
109− color: "white"
110− opacity: 0.8
111− fontSize: "xx-small"
112− elide: Text.ElideRight
113− maximumLineCount: 2
114− wrapMode: Text.WordWrap
115− onTextChanged: checkSizeForRemoteDetails()
116− }
117−
118− Label {
119− id: labelRemotePostTime
120−
121− width: parent.width
122− text: model.remotePostTime ? model.remotePostTime : ""
123− color: "white"
124− opacity: 0.5
125− fontSize: "xx-small"
126− elide: Text.ElideRight
127− visible: showRemoteDetails
128− onTextChanged: checkSizeForRemoteDetails()
129− }
130− }
131−
132− onHeightChanged: checkSizeForRemoteDetails()
133− onWidthChanged: checkSizeForRemoteDetails()
134− Component.onCompleted: checkSizeForRemoteDetails()
135− }
136− }
137−
138− Loader {
139− id: loader_frame
140−
141− anchors {
142− left: parent.left
143− right: parent.right
144− bottom: parent.bottom
145− }
146− height: item.frameHeight
147− opacity: item.explicitlyScaled ? 1.0 : 0
148−
149− Behavior on opacity {
150− NumberAnimation {
151− duration: 250
152− easing.type: Easing.InOutQuad
153− }
154− }
155−
156− sourceComponent: opacity > 0 ? component_frame : undefined
157− }
158−
159− BorderImage {
160− anchors.centerIn: parent
161− opacity: 0.6
162− source: "../../Components/graphics/non-selected.sci"
163− width: parent.width + units.gu(1.5)
164− height: parent.height + units.gu(1.5)
165− }
166−}
Dash/People/Data.qmldeleted−71
@@ -1,71 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import Dee 3.0
19−
20−DeeVariantText {
21− property string uri
22− property string name
23− property url avatar
24− property var emails: ListModel {}
25− property var phones: ListModel {}
26− property string presenceStatus
27− property string presenceMessage
28− property url remoteSourceIcon
29− property string remotePost
30− property bool favorite
31− property bool recent
32− property url statusIcon
33− property string status: remotePost ? remotePost : presenceMessage
34− property url recentIcon
35− property string recentTime
36−
37− statusIcon: switch(presenceStatus) {
38− case "offline": "graphics/icon_offline.png"; break
39− // FIXME random for now, as we don't get actual presence data on the phone
40− case "":
41− var r = Math.random();
42− if (r >= 0.7) "graphics/icon_online.png"
43− else if (r >= 0.4) "graphics/icon_offline.png"
44− else "graphics/icon_unknown.png"
45− break;
46− default: "graphics/icon_online.png"
47− }
48−
49− onValueChanged: {
50− for (var i in value) switch (value[i][0]) {
51− case "presence-message": presenceMessage = value[i][1]; break
52− case "presence-status": presenceStatus = value[i][1]; break
53− case "remote-source-icon": remoteSourceIcon = value[i][1]; break
54− case "remote-post": remotePost = value[i][1]; break
55− case "recent-icon": recentIcon = value[i][1]; break
56− case "recent-time": recentTime = value[i][1]; break
57− case "phone": phones.append({"type": generateType(), "number": value[i][1]}); break
58− case "email": emails.append({"type": generateType(), "address": value[i][1]}); break
59− }
60− }
61−
62− // FIXME: random for now, as we don't have multiple phone numbers in the backend yet
63− function generateType() {
64− var phoneType = "";
65− var r = Math.random();
66− if (r >= 0.7) phoneType = "Private";
67− else if (r >= 0.4) phoneType = "Mobile";
68− else phoneType = "Work";
69− return phoneType;
70− }
71−}
Dash/People/Delegate.qmldeleted−167
@@ -1,167 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
19−import "../../Components"
20−import "../../Components/Time.js" as Time
21−
22−Item {
23− id: peopleView
24−
25− property var dataModel
26−
27− property int __spacing: units.gu(1)
28−
29− /* Select what is shown in the subtitle
30− data: phone number or email address
31− status: social media presence status
32− */
33− property string subtitleType: "data"
34− height: subtitleType == "data" && detailsLabel.lineCount < 2 ? units.gu(10) : units.gu(11.5)
35−
36− Row {
37− id: row
38− anchors {
39− left: parent.left
40− right: parent.right
41− leftMargin: units.gu(2)
42− rightMargin: units.gu(4)
43− top: parent.top
44− topMargin: units.gu(2)
45− }
46− spacing: __spacing
47−
48− UbuntuShape {
49− id: avatar
50− anchors { top: parent.top }
51− width: units.gu(6)
52− height: units.gu(6)
53− image: Image {
54− width: units.gu(6)
55− source: peopleView.dataModel.avatar
56− sourceSize { width: avatar.width; height: avatar.height }
57− fillMode: Image.PreserveAspectCrop
58− smooth: true
59− asynchronous: true
60− cache: false
61− }
62− }
63−
64− Grid {
65− spacing: units.gu(0.5)
66− width: parent.width - x
67− columns: 2
68−
69− Item {
70− height: units.gu(2)
71− width: units.gu(2)
72−
73− Image {
74− id: statusImage
75− source: peopleView.dataModel.statusIcon
76− width: units.gu(1.5)
77− height: units.gu(1.5)
78− fillMode: Image.PreserveAspectFit
79− smooth: true
80− anchors.verticalCenter: parent.verticalCenter
81− }
82− }
83−
84− Label {
85− id: nameLabel
86− elide: Text.ElideRight
87− text: peopleView.dataModel.name
88− color: "#f3f3e7"
89− style: Text.Raised
90− styleColor: "black"
91− font.weight: Font.DemiBold;
92− opacity: 0.9;
93− }
94−
95− Image {
96− source: switch(peopleView.subtitleType) {
97− case "data":
98− return peopleView.dataModel.remoteSourceIcon;
99− case "status":
100− return peopleView.dataModel.recent ? peopleView.dataModel.recentIcon : "";
101− }
102−
103− width: units.gu(1.5)
104− height: units.gu(1.5)
105− fillMode: Image.PreserveAspectFit
106− smooth: true
107− }
108−
109− Label {
110− id: detailsLabel
111− width: parent.width - x
112− elide: Text.ElideRight
113− text: switch (peopleView.subtitleType) {
114− case "data":
115− if (peopleView.dataModel.phones && peopleView.dataModel.phones.count > 0) {
116− return peopleView.dataModel.phones.get(0).number;
117− } else if (peopleView.dataModel.emails && peopleView.dataModel.emails.count > 0) {
118− return peopleView.dataModel.emails.get(0).address;
119− }
120− return "";
121− case "status":
122− return peopleView.dataModel.status;
123− }
124− color: "#f3f3e7"
125− style: Text.Raised
126− styleColor: "black"
127− opacity: 0.7;
128− fontSize: "small";
129− wrapMode: Text.WordWrap;
130− maximumLineCount: 2;
131− }
132−
133− Item {
134− height: units.gu(2)
135− width: units.gu(1.5)
136−
137− // Placeholder
138− }
139−
140− Label {
141− width: parent.width - x
142− elide: Text.ElideRight
143− text: switch (peopleView.subtitleType) {
144− case "data":
145− if (peopleView.dataModel.phones && peopleView.dataModel.phones.count > 0) {
146− return peopleView.dataModel.phones.get(0).type;
147− } else if (peopleView.dataModel.emails && peopleView.dataModel.emails.count > 0) {
148− return peopleView.dataModel.emails.get(0).type;
149− }
150− return "";
151− case "status":
152− if (peopleView.dataModel.recent) {
153− var time = Time.readableFromNow(peopleView.dataModel.recentTime);
154− return time ? time : peopleView.dataModel.recentTime;
155− } else {
156− return peopleView.dataModel.status
157− }
158− }
159− color: "#8f8f88"
160− style: Text.Raised
161− styleColor: "black"
162− opacity: 0.7;
163− fontSize: "x-small";
164− }
165− }
166− }
167−}
Dash/People/PeopleCarousel.qmldeleted−43
@@ -1,43 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import "../../Components"
19−
20−Carousel {
21− id: peopleCarousel
22− tileAspectRatio: 1
23− minimumTileWidth: units.gu(13)
24− itemComponent: carouselDelegatePeople
25− selectedItemScaleFactor: 1.2
26− cacheBuffer: 1404 // 18px * 13gu * 6
27− height: implicitHeight + units.gu(6)
28−
29− Component {
30− id: carouselDelegatePeople
31− CarouselDelegatePeople {
32− dataModel: data
33−
34− Data {
35− id: data
36− uri: model.column_0
37− text: model.column_5
38− name: model.column_4
39− avatar: model.column_1
40− }
41− }
42− }
43−}
Dash/People/PeopleFilterGrid.qmldeleted−74
@@ -1,74 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import "../../Components"
19−import "../../Components/ListItems" as ListItems
20−
21−FilterGrid {
22− id: filterGrid
23−
24− filter: true
25− minimumHorizontalSpacing: 0
26− delegateWidth: units.gu(40)
27− delegateHeight: showStatusMessage ? units.gu(11.5) : units.gu(10)
28− verticalSpacing: 0
29− collapsedRowCount: 50 / columns
30− expandable: false
31−
32− property int categoryId
33− property bool showStatusMessage: categoryId == 1 || categoryId == 2
34−
35− readonly property int columnCount: width / cellWidth
36−
37− signal clicked(int index, variant data, real itemY)
38−
39− delegate: ListItems.Base {
40− id: tile
41− objectName: "delegate" + index
42− width: filterGrid.cellWidth
43− showDivider: index < Math.floor((filterGrid.model.count-1) / filterGrid.columnCount) * filterGrid.columnCount
44−
45− onClicked: {
46− filterGrid.clicked(index, data, tile.y);
47− }
48−
49− Delegate {
50− width: filterGrid.cellWidth
51− height: filterGrid.cellHeight
52− // This caches the Delegate into FBO because:
53− // - People data Delegates are slow because of their item count
54− // - FilterGrid is "height: childrenRect.height" so all delegates are always loaded
55− // TODO: Optimize this by:
56− // - not loading all delegates all the time and remove layer.enabled and/or
57− // - destroy whole lens when not visible/needed to free the GPU memory
58− layer.enabled: true
59−
60− dataModel: data
61− subtitleType: filterGrid.showStatusMessage ? "status" : "data"
62−
63− Data {
64− id: data
65− uri: column_0
66− text: column_5
67− name: column_4
68− avatar: column_1
69− favorite: filterGrid.categoryId == 0
70− recent: filterGrid.showStatusMessage
71− }
72− }
73− }
74−}
Dash/People/PeoplePreview.qmldeleted−124
@@ -1,124 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
19−import "../../Components"
20−import "../../Components/ListItems" as ListItems
21−import ".."
22−import "Preview"
23−
24−DashPreview {
25− id: preview
26−
27− property var model: undefined
28−
29− title: (model && model.displayName) ? model.displayName : ""
30− url: (model && model.avatar) ? model.avatar : ""
31− previewWidthRatio: 0.34
32−
33−
34− description: Grid {
35− spacing: columns > 1 ? units.gu(2) : 0
36− columns: preview.narrowMode || width < units.gu(60) ? 1 : 2
37− property int columnWidth: columns > 1 ? (width - spacing * (columns - 1)) / columns : width
38− anchors {
39− left: parent.left
40− right: parent.right
41− }
42−
43− Status {
44− id: status
45− objectName: "statusField"
46− width: parent.columnWidth
47− visible: preview.model != undefined && preview.model.status != undefined
48− model: preview.model
49− property int index: 1
50− // FIXME that should trigger the action on the lens/scope, when there's support
51− onClicked: shell.activateApplication("/usr/share/applications/%1-webapp.desktop".arg(model.statusService), "--homepage=%1".arg(model.statusPostUri))
52− }
53−
54−
55− Column {
56− id: descriptionColumn
57− width: parent.columnWidth
58−
59−
60− Column {
61− anchors {
62− left: parent.left
63− right: parent.right
64− }
65−
66− Repeater {
67− model: preview.model ? preview.model.phoneNumbers : undefined
68−
69− delegate: Phone {
70− objectName: "phoneField" + index
71− model: preview.model
72− // FIXME these should trigger actions on the lens/scope, when there's support
73− onPhoneClicked: shell.activateApplication("/usr/share/applications/phone-app.desktop", "call://%1".arg(number.replace(/[^\d\+]/g, "")))
74− onTextClicked: shell.activateApplication("/usr/share/applications/phone-app.desktop", "message://%1".arg(number.replace(/[^\d\+]/g, "")))
75− }
76− }
77− }
78−
79− Column {
80− anchors {
81− left: parent.left
82− right: parent.right
83− }
84−
85− Repeater {
86− model: preview.model ? preview.model.emailAddresses : undefined
87− delegate: Generic {
88− objectName: "emailField" + index
89− type: "email"
90− }
91− }
92− }
93−
94− Column {
95− anchors {
96− left: parent.left
97− right: parent.right
98− }
99−
100− Repeater {
101− model: preview.model ? preview.model.imAccounts : undefined
102− delegate: Generic {
103− objectName: "imField" + index
104− type: "imAccount"
105− }
106− }
107− }
108−
109− Column {
110− anchors {
111− left: parent.left
112− right: parent.right
113− }
114−
115− Repeater {
116− model: preview.model ? preview.model.addresses : undefined
117− delegate: Address {
118− objectName: "addressField" + index
119− }
120− }
121− }
122− }
123− }
124−}
Dash/People/Preview/Address.qmldeleted−74
@@ -1,74 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
19−
20−Base {
21− id: root
22−
23− Item {
24− anchors {
25− left: parent.left
26− right: parent.right
27− leftMargin: units.gu(2)
28− rightMargin: units.gu(4)
29− }
30− height: childrenRect.height + units.gu(2.5)
31−
32− Label {
33− id: typeLabel
34− anchors {
35− top: parent.top
36− topMargin: units.gu(1)
37− }
38− text: type
39− elide: Text.ElideRight
40− color: "#f3f3e7"
41− style: Text.Raised
42− styleColor: "black"
43− font.capitalization: Font.Capitalize
44− opacity: 0.7;
45− fontSize: "small"
46− }
47−
48− Label {
49− id: contentLabel
50− anchors {
51− left: parent.left
52− right: parent.right
53− top: typeLabel.bottom
54− topMargin: units.gu(0.5)
55− }
56− text: {
57− var fields = [street, poBox, extension, locality, region, postalCode, country, addressFormat]
58− var parts = []
59− for (var k in fields) {
60− if (fields[k]) parts.push(fields[k])
61− }
62− return parts.join("\n")
63− }
64− elide: Text.ElideRight
65− color: "#f3f3e7"
66− style: Text.Raised
67− styleColor: "black"
68− opacity: 0.9;
69− fontSize: "large"
70− wrapMode: Text.WordWrap
71− font.weight: Font.Light
72− }
73− }
74−}
Dash/People/Preview/Base.qmldeleted−22
@@ -1,22 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import "../../../Components/ListItems"
19−
20−Base {
21− property var model
22−}
Dash/People/Preview/Generic.qmldeleted−80
@@ -1,80 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
19−
20−Base {
21− id: root
22−
23− property string type
24−
25− Item {
26− anchors {
27− left: parent.left
28− right: parent.right
29− leftMargin: units.gu(2)
30− rightMargin: units.gu(4)
31− }
32− height: childrenRect.height + units.gu(2.5)
33−
34− Label {
35− id: typeLabel
36− anchors {
37− top: parent.top
38− topMargin: units.gu(1)
39− }
40− text: switch (root.type) {
41− case "email":
42− case "address": type; break
43− case "imAccount": protocol; break
44− default: type
45− }
46− elide: Text.ElideRight
47− color: "#f3f3e7"
48− style: Text.Raised
49− styleColor: "black"
50− font.capitalization: Font.Capitalize
51− opacity: 0.7;
52− fontSize: "small"
53− }
54−
55− Label {
56− id: contentLabel
57− anchors {
58− left: parent.left
59− right: parent.right
60− top: typeLabel.bottom
61− topMargin: units.gu(0.5)
62− }
63− text: switch (root.type) {
64− case "email":
65− case "address":
66− case "imAccount": address; break
67− default: text
68− }
69− elide: Text.ElideRight
70− color: "#f3f3e7"
71− style: Text.Raised
72− styleColor: "black"
73− opacity: 0.9;
74− fontSize: "large"
75− wrapMode: Text.WordWrap
76− maximumLineCount: 2
77− font.weight: Font.Light
78− }
79− }
80−}
Dash/People/Preview/Phone.qmldeleted−108
@@ -1,108 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
19−import "../../../Components/ListItems" as ListItems
20−
21−Base {
22− id: root
23− highlightWhenPressed: false
24−
25− signal phoneClicked
26− signal textClicked
27−
28− Row {
29− height: phoneButton.height
30− anchors {
31− left: parent.left
32− right: parent.right
33− }
34− AbstractButton {
35− id: phoneButton
36− width: parent.width - units.gu(7)
37− height: Math.max(units.gu(8), phoneColumn.height + units.gu(2))
38− Column {
39− id: phoneColumn
40− spacing: units.gu(0.5)
41− anchors {
42− top: parent.top
43− topMargin: units.gu(1)
44− left: parent.left
45− leftMargin: units.gu(2)
46− right: parent.right
47− }
48− Label {
49− text: {
50− var parts = []
51− if (location) parts.push(location)
52− if (type && type != "voice") parts.push(type)
53− if (parts.length == 0) return "other"
54− return parts.join(" ")
55− }
56− elide: Text.ElideRight
57− color: "#f3f3e7"
58− style: Text.Raised
59− styleColor: "black"
60− font.capitalization: Font.Capitalize
61− opacity: 0.7;
62− fontSize: "small"
63− }
64− Label {
65− width: parent.width
66− text: number
67− elide: Text.ElideRight
68− color: "#f3f3e7"
69− style: Text.Raised
70− styleColor: "black"
71− opacity: 0.9;
72− fontSize: "large"
73− wrapMode: Text.WordWrap
74− maximumLineCount: 2
75− font.weight: Font.Light
76− }
77− }
78−
79− ListItems.Highlight {
80− anchors.fill: parent
81− pressed: phoneButton.pressed
82− }
83−
84− onClicked: phoneClicked()
85− }
86−
87− AbstractButton {
88− id: textButton
89− width: units.gu(7)
90− height: parent.height
91−
92− Image {
93− anchors.centerIn: parent
94− width: units.gu(4)
95− height: units.gu(4)
96− source: "../graphics/icon_write_text.png"
97− fillMode: Image.PreserveAspectFit
98− }
99−
100− ListItems.Highlight {
101− anchors.fill: parent
102− pressed: textButton.pressed
103− }
104−
105− onClicked: textClicked()
106− }
107− }
108−}
Dash/People/Preview/Status.qmldeleted−97
@@ -1,97 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
19−import "../../../Components/Time.js" as Time
20−
21−Base {
22− id: root
23−
24− Item {
25− anchors {
26− left: parent.left
27− right: parent.right
28− leftMargin: units.gu(2)
29− rightMargin: units.gu(4)
30− }
31− height: childrenRect.height
32−
33− Label {
34− id: typeLabel
35− anchors {
36− top: parent.top
37− topMargin: units.gu(1)
38− }
39− text: "Status"
40− elide: Text.ElideRight
41− color: "#f3f3e7"
42− style: Text.Raised
43− styleColor: "black"
44− font.capitalization: Font.Capitalize
45− opacity: 0.7;
46− fontSize: "small"
47− }
48−
49− Label {
50− id: contentLabel
51− anchors {
52− left: parent.left
53− right: parent.right
54− top: typeLabel.bottom
55− topMargin: units.gu(0.5)
56− }
57− text: root.model ? root.model.status : ""
58− elide: Text.ElideRight
59− color: "#f3f3e7"
60− style: Text.Raised
61− styleColor: "black"
62− opacity: 0.9;
63− fontSize: "large"
64− wrapMode: Text.WordWrap
65− maximumLineCount: 6
66− font.weight: Font.Light
67− }
68−
69− Row {
70− anchors {
71− top: contentLabel.bottom
72− topMargin: units.gu(1)
73− }
74− height: statusText.height + units.gu(2.5)
75− spacing: units.gu(1)
76− Image {
77− width: units.gu(2)
78− height: units.gu(2)
79− fillMode: Image.PreserveAspectFit
80− source: root.model ? root.model.statusServiceIcon : ""
81− }
82− Label {
83− id: statusText
84− text: if (root.model) {
85− var time = Time.readableFromNow(root.model.statusTime);
86− return time ? time : root.model.statusTime;
87− } else return "";
88− elide: Text.ElideRight
89− color: "#f3f3e7"
90− style: Text.Raised
91− styleColor: "black"
92− opacity: 0.7;
93− fontSize: "small"
94− }
95− }
96− }
97−}
Dash/People/graphics/bottomshape@18.pngdeleted

Binary file not shown.

Dash/People/graphics/bottomshape@18.scideleted−5
@@ -1,5 +0,0 @@
1−border.left: 54
2−border.top: 60
3−border.bottom: 60
4−border.right: 54
5−source: bottomshape@18.png
Dash/People/graphics/icon_facebook@18.pngdeleted

Binary file not shown.

Dash/People/graphics/icon_offline@18.pngdeleted

Binary file not shown.

Dash/People/graphics/icon_online@18.pngdeleted

Binary file not shown.

Dash/People/graphics/icon_twitter@18.pngdeleted

Binary file not shown.

Dash/People/graphics/icon_unknown@18.pngdeleted

Binary file not shown.

Dash/People/graphics/icon_write_text@18.pngdeleted

Binary file not shown.

Dash/People/graphics/star_favourite@18.pngdeleted

Binary file not shown.

Dash/People/graphics/star_not_favourite@18.pngdeleted

Binary file not shown.

Dash/LensDelegateMapper.qml → Dash/ScopeDelegateMapper.qmlrenamed+10−11
@@ -17,19 +17,18 @@
1717import QtQuick 2.0
1818
1919QtObject {
20− property var lensDelegateMapping: {"mockmusic.lens": "DashMusic.qml",
21− "applications.lens": "DashApps.qml",
22− "home.lens": "DashHome.qml",
23− "mockvideos.lens": "DashVideos.qml",
24− "people.lens": "DashPeople.qml",
20+ property var scopeDelegateMapping: {"mockmusicmaster.scope": "DashMusic.qml",
21+ "applications.scope": "DashApps.qml",
22+ "home.scope": "DashHome.qml",
23+ "mockvideosmaster.scope": "DashVideos.qml"
2524 }
26− property string genericLens: "GenericLensView.qml"
25+ property string genericScope: "GenericScopeView.qml"
2726
28− function map(lensId) {
29− var customLens = lensDelegateMapping[lensId]
30− if (customLens != undefined) {
31− return customLens
27+ function map(scopeId) {
28+ var customScope = scopeDelegateMapping[scopeId]
29+ if (customScope != undefined) {
30+ return customScope
3231 }
33− return genericLens
32+ return genericScope
3433 }
3534}
Dash/LensView.qml → Dash/ScopeView.qmlrenamed+4−4
@@ -19,7 +19,7 @@ import Utils 0.1
1919import Unity 0.1
2020
2121FocusScope {
22− property Lens lens
22+ property Scope scope
2323 property SortFilterProxyModel categories: categoryFilter
2424 property bool isCurrent
2525 property ListModel searchHistory
@@ -29,17 +29,17 @@ FocusScope {
2929 signal positionedAtBeginning
3030
3131 // FIXME delay the search so that daemons have time to settle
32− onLensChanged: timer.restart()
32+ onScopeChanged: timer.restart()
3333
3434 Timer {
3535 id: timer
3636 interval: 2000
37− onTriggered: lens.searchQuery = ""
37+ onTriggered: scope.searchQuery = ""
3838 }
3939
4040 SortFilterProxyModel {
4141 id: categoryFilter
42− model: lens.categories
42+ model: scope.categories
4343 dynamicSortFilter: true
4444 filterRole: Categories.RoleCount
4545 filterRegExp: /^0$/
Dash/Video/VideosFilterGrid.qml+2−2
@@ -37,14 +37,14 @@ FilterGrid {
3737 objectName: "delegate" + index
3838 width: filtergrid.cellWidth
3939 height: filtergrid.cellHeight
40− text: model.column_4
40+ text: model.column_5
4141 imageWidth: filtergrid.iconWidth
4242 imageHeight: filtergrid.iconHeight
4343 source: model.column_1
4444 fillMode: Image.PreserveAspectCrop
4545 onClicked: {
4646 var fileUri = model.column_0.replace(/^[^:]+:/, "")
47− var data = {fileUri: fileUri, nfoUri: model.column_5}
47+ var data = {fileUri: fileUri, nfoUri: model.column_6}
4848 filtergrid.clicked(index, data, tile.y);
4949 }
5050 }
Dash/graphics/lensIcons/Applications@18.pngdeleted

Binary file not shown.

Dash/graphics/lensIcons/Home@18.pngdeleted

Binary file not shown.

Dash/graphics/lensIcons/Music@18.pngdeleted

Binary file not shown.

Dash/graphics/lensIcons/People@18.pngdeleted

Binary file not shown.

Dash/graphics/lensIcons/Videos@18.pngdeleted

Binary file not shown.

Shell.qml+3−3
@@ -552,14 +552,14 @@ FocusScope {
552552 greeter.hide()
553553 // Animate if moving between application and dash
554554 if (!stages.shown) {
555− dash.setCurrentLens("home.lens", true, false)
555+ dash.setCurrentScope("home.scope", true, false)
556556 } else {
557− dash.setCurrentLens("home.lens", false, false)
557+ dash.setCurrentScope("home.scope", false, false)
558558 }
559559 stages.hide();
560560 }
561561 onDash: {
562− dash.setCurrentLens("applications.lens", true, false)
562+ dash.setCurrentScope("applications.scope", true, false)
563563 stages.hide();
564564 }
565565 onLauncherApplicationSelected:{
build_unity+5−15
@@ -6,11 +6,10 @@ SETUP=false
66UPDATE=false
77CLEAN=false
88NUM_JOBS=$(( `grep -c ^processor /proc/cpuinfo` + 1 ))
9−LENSES="applications mockmusic mockvideos"
109
1110# verified working revisions
12−LIBUNITY_REV=215
13−UNITY_REV=3260
11+LIBUNITY_REV=228
12+UNITY_REV=3343
1413HUD_REV=252
1514
1615usage() {
@@ -53,12 +52,12 @@ mk_build_deps() {
5352
5453branch_libunity() {
5554 echo "Branching libunity.."
56− bzr branch lp:libunity/phablet $TARGET_DIR/libunity || exit 8
55+ bzr branch lp:libunity $TARGET_DIR/libunity || exit 8
5756}
5857
5958branch_unity() {
6059 echo "Branching Unity.."
61− bzr branch lp:unity/phablet-mods $TARGET_DIR/unity || exit 9
60+ bzr branch lp:unity $TARGET_DIR/unity || exit 9
6261}
6362
6463branch_hud() {
@@ -92,7 +91,7 @@ compile_libunity() {
9291 mkdir $TARGET_DIR/libunity/build
9392 cd $TARGET_DIR/libunity/build
9493
95− ../autogen.sh --prefix $BUILD_DIR --disable-debug || exit 15
94+ ../autogen.sh --prefix $BUILD_DIR --disable-debug --with-pygi-overrides-dir=$BUILD_DIR/gi-overrides || exit 15
9695
9796 echo "Building libunity and installing in " $BUILD_DIR
9897 make -j$NUM_JOBS install || exit 16
@@ -136,14 +135,6 @@ compile_hud() {
136135
137136}
138137
139−link_lenses() {
140− echo "Linking system lenses.."
141− mkdir -p $BUILD_DIR/share/unity/lenses/
142− for LENS in $LENSES; do
143− [ -e $BUILD_DIR/share/unity/lenses/$LENS ] || ln -ivs /usr/share/unity/lenses/$LENS $BUILD_DIR/share/unity/lenses/$LENS
144− done
145−}
146−
147138if $SETUP; then
148139 echo "Setting up environment for building Unity.."
149140 install_utils
@@ -163,6 +154,5 @@ else
163154 compile_libunity
164155 compile_unity_core
165156 compile_hud
166− link_lenses
167157fi
168158
debian/changelog+6
@@ -1,3 +1,9 @@
1+unity8 (7.81.0) UNRELEASED; urgency=low
2+
3+ * New version with support for smart scopes.
4+
5+ -- Michał Sawicz <michal.sawicz@canonical.com> Fri, 14 Jun 2013 12:56:17 +0200
6+
17unity8 (7.80.0) saucy; urgency=low
28
39 * Rename to unity8.
debian/control+3−1
@@ -11,7 +11,7 @@ Build-Depends: cmake,
1111 libgles2-mesa-dev[armhf],
1212 libhud-client2-dev,
1313 libpulse-dev,
14− libunity-core-6.0-dev,
14+ libunity-core-6.0-dev (<< 7.80),
1515 libxcb1-dev,
1616 pkg-config,
1717 python3,
@@ -51,6 +51,8 @@ Recommends: indicators-client-plugin-datetime (>= 0.6.1),
5151 indicators-client-plugin-network (>= 0.6.1),
5252 indicators-client-plugin-power (>= 0.6.1),
5353 indicators-client-plugin-sound (>= 0.6.1),
54+ unity-scope-home,
55+ unity-lens-applications,
5456Description: Ubuntu QML shell
5557 The Ubuntu QML shell is the primary user interface for Ubuntu devices.
5658
plugins/Unity/CMakeLists.txt+2−3
@@ -13,11 +13,10 @@ include_directories(
1313
1414set(QMLPLUGIN_SRC
1515 ../Utils/qsortfilterproxymodelqml.cpp # FIXME evaluate a more generic approach for using other plugins
16− lens.cpp
17− lenses.cpp
16+ scope.cpp
17+ scopes.cpp
1818 categories.cpp
1919 categoryfilter.cpp
20− peoplepreviewdata.cpp
2120 plugin.cpp
2221 bottombarvisibilitycommunicatorshell.cpp
2322 launchermodel.cpp
plugins/Unity/categories.cpp+4−54
@@ -24,7 +24,6 @@
2424Categories::Categories(QObject* parent)
2525 : DeeListModel(parent)
2626 , m_resultModel(0)
27− , m_globalResultModel(0)
2827{
2928 // FIXME: need to clean up unused filters on countChanged
3029 m_roles[Categories::RoleId] = "id";
@@ -33,9 +32,7 @@ Categories::Categories(QObject* parent)
3332 m_roles[Categories::RoleRenderer] = "renderer";
3433 m_roles[Categories::RoleHints] = "hints";
3534 m_roles[Categories::RoleResults] = "results";
36− m_roles[Categories::RoleGlobalResults] = "globalResults";
3735 m_roles[Categories::RoleCount] = "count";
38− m_roles[Categories::RoleGlobalCount] = "globalCount";
3936
4037 // TODO This should not be needed but accumulatting the count changes
4138 // makes the visualization more stable and also makes crashes on fast
@@ -48,7 +45,6 @@ Categories::Categories(QObject* parent)
4845Categories::~Categories()
4946{
5047 qDeleteAll(m_filters);
51− qDeleteAll(m_globalFilters);
5248}
5349
5450CategoryFilter*
@@ -66,21 +62,6 @@ Categories::getFilter(int index) const
6662 return m_filters[index];
6763}
6864
69−CategoryFilter*
70−Categories::getGlobalFilter(int index) const
71−{
72− if (!m_globalFilters.contains(index)) {
73− CategoryFilter* filter = new CategoryFilter();
74− connect(filter, SIGNAL(countChanged()), this, SLOT(onGlobalCountChanged()));
75− filter->setModel(m_globalResultModel);
76− filter->setIndex(index);
77−
78− m_globalFilters.insert(index, filter);
79− }
80−
81− return m_globalFilters[index];
82−}
83−
8465void
8566Categories::setResultModel(DeeListModel* model)
8667{
@@ -95,20 +76,6 @@ Categories::setResultModel(DeeListModel* model)
9576 }
9677}
9778
98−void
99−Categories::setGlobalResultModel(DeeListModel* model)
100−{
101− if (model != m_globalResultModel) {
102− m_globalResultModel = model;
103−
104− Q_FOREACH(CategoryFilter* filter, m_globalFilters) {
105− filter->setModel(m_globalResultModel);
106− }
107−
108− Q_EMIT globalResultModelChanged(m_globalResultModel);
109− }
110−}
111−
11279void
11380Categories::onCountChanged()
11481{
@@ -131,18 +98,6 @@ Categories::onEmitCountChanged()
13198 m_timerFilters.clear();
13299}
133100
134−void
135−Categories::onGlobalCountChanged()
136−{
137− CategoryFilter* filter = qobject_cast<CategoryFilter*>(sender());
138− if (filter) {
139− QModelIndex changedIndex = index(filter->index());
140− QVector<int> roles;
141− roles.append(Categories::RoleGlobalCount);
142− Q_EMIT dataChanged(changedIndex, changedIndex, roles);
143− }
144−}
145−
146101QHash<int, QByteArray>
147102Categories::roleNames() const
148103{
@@ -159,23 +114,18 @@ Categories::data(const QModelIndex& index, int role) const
159114 if (role == RoleId) {
160115 return QVariant::fromValue(index.row());
161116 } else if (role == RoleName) {
162− return QVariant::fromValue(DeeListModel::data(index, 0));
117+ return QVariant::fromValue(DeeListModel::data(index, 1)); //DISPLAY_NAME
163118 } else if (role == RoleIcon) {
164− return QVariant::fromValue(DeeListModel::data(index, 1));
119+ return QVariant::fromValue(DeeListModel::data(index, 2)); //ICON_HINT
165120 } else if (role == RoleRenderer) {
166− return QVariant::fromValue(DeeListModel::data(index, 2));
121+ return QVariant::fromValue(DeeListModel::data(index, 3)); //RENDERER_NAME
167122 } else if (role == RoleHints) {
168− return QVariant::fromValue(DeeListModel::data(index, 3));
123+ return QVariant::fromValue(DeeListModel::data(index, 4)); //HINTS
169124 } else if (role == RoleResults) {
170125 return QVariant::fromValue(getFilter(index.row()));
171− } else if (role == RoleGlobalResults) {
172− return QVariant::fromValue(getGlobalFilter(index.row()));
173126 } else if (role == RoleCount) {
174127 CategoryFilter* filter = getFilter(index.row());
175128 return QVariant::fromValue(filter->rowCount());
176− } else if (role == RoleGlobalCount) {
177− QSortFilterProxyModel* filter = getGlobalFilter(index.row());
178− return QVariant::fromValue(filter->rowCount());
179129 } else {
180130 return QVariant();
181131 }
plugins/Unity/categories.h+1−11
@@ -36,7 +36,6 @@ class Categories : public DeeListModel
3636 Q_ENUMS(Roles)
3737
3838 Q_PROPERTY(DeeListModel* resultModel READ resultModel WRITE setResultModel NOTIFY resultModelChanged)
39− Q_PROPERTY(DeeListModel* globalResultModel READ globalResultModel WRITE setResultModel NOTIFY globalResultModelChanged)
4039
4140public:
4241 explicit Categories(QObject* parent = 0);
@@ -49,9 +48,7 @@ public:
4948 RoleRenderer,
5049 RoleHints,
5150 RoleResults,
52− RoleGlobalResults,
53− RoleCount,
54− RoleGlobalCount
51+ RoleCount
5552 };
5653
5754 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
@@ -60,32 +57,25 @@ public:
6057
6158 /* getters */
6259 DeeListModel* resultModel() { return m_resultModel; }
63− DeeListModel* globalResultModel() { return m_globalResultModel; }
6460
6561 /* setters */
6662 void setResultModel(DeeListModel*);
67− void setGlobalResultModel(DeeListModel*);
6863
6964Q_SIGNALS:
7065 void resultModelChanged(DeeListModel*);
71− void globalResultModelChanged(DeeListModel*);
7266
7367private Q_SLOTS:
7468 void onCountChanged();
75− void onGlobalCountChanged();
7669 void onEmitCountChanged();
7770
7871private:
7972 CategoryFilter* getFilter(int index) const;
80− CategoryFilter* getGlobalFilter(int index) const;
8173
8274 QTimer m_timer;
8375 QSet<CategoryFilter*> m_timerFilters;
8476 QHash<int, QByteArray> m_roles;
8577 DeeListModel* m_resultModel;
86− DeeListModel* m_globalResultModel;
8778 mutable QMap<int, CategoryFilter*> m_filters;
88− mutable QMap<int, CategoryFilter*> m_globalFilters;
8979};
9080
9181#endif // CATEGORIES_H
plugins/Unity/lens.cppdeleted−338
@@ -1,338 +0,0 @@
1−/*
2− * Copyright (C) 2011 Canonical, Ltd.
3− *
4− * Authors:
5− * Florian Boucault <florian.boucault@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−// Self
21−#include "lens.h"
22−#include "categories.h"
23−
24−// Qt
25−#include <QUrl>
26−#include <QDebug>
27−#include <QtGui/QDesktopServices>
28−
29−#include <libintl.h>
30−
31−Lens::Lens(QObject *parent) :
32− QObject(parent)
33−{
34− m_results = new DeeListModel(this);
35− m_globalResults = new DeeListModel(this);
36− m_categories = new Categories(this);
37−
38− m_categories->setResultModel(m_results);
39− m_categories->setGlobalResultModel(m_globalResults);
40−}
41−
42−QString Lens::id() const
43−{
44− return QString::fromStdString(m_unityLens->id());
45−}
46−
47−QString Lens::dbusName() const
48−{
49− return QString::fromStdString(m_unityLens->dbus_name());
50−}
51−
52−QString Lens::dbusPath() const
53−{
54− return QString::fromStdString(m_unityLens->dbus_path());
55−}
56−
57−QString Lens::name() const
58−{
59− return QString::fromStdString(m_unityLens->name());
60−}
61−
62−QString Lens::iconHint() const
63−{
64− return QString::fromStdString(m_unityLens->icon_hint());
65−}
66−
67−QString Lens::description() const
68−{
69− return QString::fromStdString(m_unityLens->description());
70−}
71−
72−QString Lens::searchHint() const
73−{
74− return QString::fromStdString(m_unityLens->search_hint());
75−}
76−
77−bool Lens::visible() const
78−{
79− return m_unityLens->visible();
80−}
81−
82−bool Lens::searchInGlobal() const
83−{
84− return m_unityLens->search_in_global();
85−}
86−
87−QString Lens::shortcut() const
88−{
89− return QString::fromStdString(m_unityLens->shortcut());
90−}
91−
92−bool Lens::connected() const
93−{
94− return m_unityLens->connected();
95−}
96−
97−DeeListModel* Lens::results() const
98−{
99− return m_results;
100−}
101−
102−DeeListModel* Lens::globalResults() const
103−{
104− return m_globalResults;
105−}
106−
107−Categories* Lens::categories() const
108−{
109− return m_categories;
110−}
111−
112−Lens::ViewType Lens::viewType() const
113−{
114− return (Lens::ViewType) m_unityLens->view_type();
115−}
116−
117−QString Lens::searchQuery() const
118−{
119− return m_searchQuery;
120−}
121−
122−QString Lens::globalSearchQuery() const
123−{
124− return m_globalSearchQuery;
125−}
126−
127−QString Lens::noResultsHint() const
128−{
129− return m_noResultsHint;
130−}
131−
132−void Lens::setViewType(const Lens::ViewType& viewType)
133−{
134− m_unityLens->view_type = (unity::dash::ViewType) viewType;
135−}
136−
137−void Lens::setSearchQuery(const QString& search_query)
138−{
139− /* Checking for m_searchQuery.isNull() which returns true only when the string
140− has never been set is necessary because when search_query is the empty
141− string ("") and m_searchQuery is the null string,
142− search_query != m_searchQuery is still true.
143− */
144− if (m_searchQuery.isNull() || search_query != m_searchQuery) {
145− m_searchQuery = search_query;
146− m_unityLens->Search(search_query.toStdString(), sigc::mem_fun(this, &Lens::searchFinished));
147− Q_EMIT searchQueryChanged();
148− }
149−}
150−
151−void Lens::setGlobalSearchQuery(const QString& search_query)
152−{
153− /* Checking for m_globalSearchQuery.isNull() which returns true only when the string
154− has never been set is necessary because when search_query is the empty
155− string ("") and m_globalSearchQuery is the null string,
156− search_query != m_globalSearchQuery is still true.
157− */
158− if (m_globalSearchQuery.isNull() || search_query != m_globalSearchQuery) {
159− m_globalSearchQuery = search_query;
160− m_unityLens->GlobalSearch(search_query.toStdString(), sigc::mem_fun(this, &Lens::globalSearchFinished));
161− Q_EMIT globalSearchQueryChanged();
162− }
163−}
164−
165−void Lens::setNoResultsHint(const QString& hint) {
166− if (hint != m_noResultsHint) {
167− m_noResultsHint = hint;
168− Q_EMIT noResultsHintChanged();
169− }
170−}
171−
172−void Lens::activate(const QString& uri)
173−{
174− m_unityLens->Activate(QByteArray::fromPercentEncoding(uri.toUtf8()).constData());
175−}
176−
177−void Lens::onActivated(std::string const& uri, unity::dash::HandledType type, unity::dash::Lens::Hints const&)
178−{
179− if (type == unity::dash::NOT_HANDLED) {
180− fallbackActivate(QString::fromStdString(uri));
181− }
182−}
183−
184−void Lens::fallbackActivate(const QString& uri)
185−{
186− /* FIXME: stripping all content before the first column because for some
187− reason the lenses give uri with junk content at their beginning.
188− */
189− QString tweakedUri = uri;
190− int firstColumnAt = tweakedUri.indexOf(":");
191− tweakedUri.remove(0, firstColumnAt+1);
192−
193− /* Tries various methods to trigger a sensible action for the given 'uri'.
194− If it has no understanding of the given scheme it falls back on asking
195− Qt to open the uri.
196− */
197− QUrl url(tweakedUri);
198− if (url.scheme() == "file") {
199− /* Override the files place's default URI handler: we want the file
200− manager to handle opening folders, not the dash.
201−
202− Ref: https://bugs.launchpad.net/upicek/+bug/689667
203− */
204− QDesktopServices::openUrl(url);
205− return;
206− }
207− if (url.scheme() == "application") {
208− // TODO: implement application handling
209− return;
210− }
211−
212− qWarning() << "FIXME: Possibly no handler for scheme: " << url.scheme();
213− qWarning() << "Trying to open" << tweakedUri;
214− /* Try our luck */
215− QDesktopServices::openUrl(url);
216−}
217−
218−void Lens::setUnityLens(const unity::dash::Lens::Ptr& lens)
219−{
220− m_unityLens = lens;
221−
222− if (QString::fromStdString(m_unityLens->results()->swarm_name) == QString(":local")) {
223− m_results->setModel(m_unityLens->results()->model());
224− } else {
225− m_results->setName(QString::fromStdString(m_unityLens->results()->swarm_name));
226− }
227− if (QString::fromStdString(m_unityLens->global_results()->swarm_name) == QString(":local")) {
228− m_globalResults->setModel(m_unityLens->global_results()->model());
229− } else {
230− m_globalResults->setName(QString::fromStdString(m_unityLens->global_results()->swarm_name));
231− }
232− if (QString::fromStdString(m_unityLens->categories()->swarm_name) == QString(":local")) {
233− m_categories->setModel(m_unityLens->categories()->model());
234− } else {
235− m_categories->setName(QString::fromStdString(m_unityLens->categories()->swarm_name));
236− }
237−
238− /* Property change signals */
239− m_unityLens->id.changed.connect(sigc::mem_fun(this, &Lens::idChanged));
240− m_unityLens->dbus_name.changed.connect(sigc::mem_fun(this, &Lens::dbusNameChanged));
241− m_unityLens->dbus_path.changed.connect(sigc::mem_fun(this, &Lens::dbusPathChanged));
242− m_unityLens->name.changed.connect(sigc::mem_fun(this, &Lens::nameChanged));
243− m_unityLens->icon_hint.changed.connect(sigc::mem_fun(this, &Lens::iconHintChanged));
244− m_unityLens->description.changed.connect(sigc::mem_fun(this, &Lens::descriptionChanged));
245− m_unityLens->search_hint.changed.connect(sigc::mem_fun(this, &Lens::searchHintChanged));
246− m_unityLens->visible.changed.connect(sigc::mem_fun(this, &Lens::visibleChanged));
247− m_unityLens->search_in_global.changed.connect(sigc::mem_fun(this, &Lens::searchInGlobalChanged));
248− m_unityLens->shortcut.changed.connect(sigc::mem_fun(this, &Lens::shortcutChanged));
249− m_unityLens->connected.changed.connect(sigc::mem_fun(this, &Lens::connectedChanged));
250− m_unityLens->results.changed.connect(sigc::mem_fun(this, &Lens::onResultsChanged));
251− m_unityLens->results()->swarm_name.changed.connect(sigc::mem_fun(this, &Lens::onResultsSwarmNameChanged));
252− m_unityLens->global_results.changed.connect(sigc::mem_fun(this, &Lens::onGlobalResultsChanged));
253− m_unityLens->global_results()->swarm_name.changed.connect(sigc::mem_fun(this, &Lens::onGlobalResultsSwarmNameChanged));
254− m_unityLens->categories.changed.connect(sigc::mem_fun(this, &Lens::onCategoriesChanged));
255− m_unityLens->categories()->swarm_name.changed.connect(sigc::mem_fun(this, &Lens::onCategoriesSwarmNameChanged));
256− m_unityLens->view_type.changed.connect(sigc::mem_fun(this, &Lens::onViewTypeChanged));
257−
258− /* Signals forwarding */
259− connect(this, SIGNAL(searchFinished(unity::dash::Lens::Hints const &, unity::glib::Error const &)), SLOT(onSearchFinished(unity::dash::Lens::Hints const &)));
260−
261− /* FIXME: signal should be forwarded instead of calling the handler directly */
262− m_unityLens->activated.connect(sigc::mem_fun(this, &Lens::onActivated));
263−
264− /* Synchronize local states with m_unityLens right now and whenever
265− m_unityLens becomes connected */
266− /* FIXME: should emit change notification signals for all properties */
267− connect(this, SIGNAL(connectedChanged(bool)), SLOT(synchronizeStates()));
268− synchronizeStates();
269−}
270−
271−unity::dash::Lens::Ptr Lens::unityLens() const
272−{
273− return m_unityLens;
274−}
275−
276−void Lens::synchronizeStates()
277−{
278− if (connected()) {
279− /* Forward local states to m_unityLens */
280− if (!m_searchQuery.isNull()) {
281− m_unityLens->Search(m_searchQuery.toStdString());
282− }
283− if (!m_globalSearchQuery.isNull()) {
284− m_unityLens->GlobalSearch(m_globalSearchQuery.toStdString());
285− }
286− }
287−}
288−
289−void Lens::onResultsSwarmNameChanged(const std::string& /* swarm_name */)
290−{
291− m_results->setName(QString::fromStdString(m_unityLens->results()->swarm_name));
292−}
293−
294−void Lens::onResultsChanged(const unity::dash::Results::Ptr& /* results */)
295−{
296− m_results->setName(QString::fromStdString(m_unityLens->results()->swarm_name));
297−}
298−
299−void Lens::onGlobalResultsSwarmNameChanged(const std::string& /* swarm_name */)
300−{
301− m_globalResults->setName(QString::fromStdString(m_unityLens->global_results()->swarm_name));
302−}
303−
304−void Lens::onGlobalResultsChanged(const unity::dash::Results::Ptr& /* global_results */)
305−{
306− m_globalResults->setName(QString::fromStdString(m_unityLens->global_results()->swarm_name));
307−}
308−
309−void Lens::onCategoriesSwarmNameChanged(const std::string& /* swarm_name */)
310−{
311− m_categories->setName(QString::fromStdString(m_unityLens->categories()->swarm_name));
312−}
313−
314−void Lens::onCategoriesChanged(const unity::dash::Categories::Ptr& /* categories */)
315−{
316− m_categories->setName(QString::fromStdString(m_unityLens->categories()->swarm_name));
317−}
318−
319−void Lens::onViewTypeChanged(unity::dash::ViewType viewType)
320−{
321− Q_EMIT viewTypeChanged( (Lens::ViewType) viewType);
322−}
323−
324−void Lens::onSearchFinished(unity::dash::Lens::Hints const &hints)
325−{
326− QString hint;
327−
328− if (!m_unityLens->results()->count()) {
329− unity::dash::Lens::Hints::const_iterator it = hints.find("no-results-hint");
330− if (it != hints.end()) {
331− hint = QString::fromStdString(it->second.GetString());
332− } else {
333− hint = QString::fromUtf8(dgettext("unity", "Sorry, there is nothing that matches your search."));
334− }
335− }
336−
337− setNoResultsHint(hint);
338−}
plugins/Unity/lenses.cppdeleted−182
@@ -1,182 +0,0 @@
1−/*
2− * Copyright (C) 2011 Canonical, Ltd.
3− *
4− * Authors:
5− * Florian Boucault <florian.boucault@canonical.com>
6− *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License as published by
9− * the Free Software Foundation; version 3.
10− *
11− * This program is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License
17− * along with this program. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−// Self
21−#include "lenses.h"
22−
23−// Local
24−#include "lens.h"
25−
26−// Qt
27−#include <QDebug>
28−#include <QtCore/QStringList>
29−#include <QtGui/QKeySequence>
30−
31−// libunity-core
32−#include <UnityCore/FilesystemLenses.h>
33−#include <UnityCore/HomeLens.h>
34−
35−Lenses::Lenses(QObject *parent)
36− : QAbstractListModel(parent)
37− , m_unityLenses(std::make_shared<unity::dash::FilesystemLenses>())
38− , m_homeLens(std::make_shared<unity::dash::HomeLens>(QString::fromUtf8(dgettext("unity", "Home")).toStdString(),
39− QString::fromUtf8(dgettext("unity", "Home screen")).toStdString(),
40− QString::fromUtf8(dgettext("unity", "Search")).toStdString()))
41− , m_loaded(false)
42−{
43− m_roles[Lenses::RoleLens] = "lens";
44− m_roles[Lenses::RoleId] = "id";
45− m_roles[Lenses::RoleVisible] = "visible";
46−
47− m_homeLens->AddLenses(m_unityLenses);
48− std::dynamic_pointer_cast<unity::dash::FilesystemLenses>(m_unityLenses)->lenses_loaded.connect(sigc::mem_fun(this, &Lenses::onLensesLoaded));
49−}
50−
51−QHash<int, QByteArray> Lenses::roleNames() const
52−{
53− return m_roles;
54−}
55−
56−int Lenses::rowCount(const QModelIndex& parent) const
57−{
58− Q_UNUSED(parent)
59−
60− return m_lenses.count();
61−}
62−
63−QVariant Lenses::data(const QModelIndex& index, int role) const
64−{
65− Q_UNUSED(role)
66−
67− if (!index.isValid()) {
68− return QVariant();
69− }
70−
71− Lens* lens = m_lenses.at(index.row());
72−
73− if (role == Lenses::RoleLens) {
74− return QVariant::fromValue(lens);
75− } else if (role == Lenses::RoleId) {
76− return QVariant::fromValue(lens->id());
77− } else if (role == Lenses::RoleVisible) {
78− return QVariant::fromValue(lens->visible());
79− } else {
80− return QVariant();
81− }
82−}
83−
84−QVariant Lenses::get(int row) const
85−{
86− return data(QAbstractListModel::index(row), 0);
87−}
88−
89−QVariant Lenses::get(const QString& lens_id) const
90−{
91− Q_FOREACH(Lens* lens, m_lenses) {
92− if (lens->id() == lens_id) {
93− return QVariant::fromValue(lens);
94− }
95− }
96−
97− return QVariant();
98−}
99−
100−bool Lenses::loaded() const
101−{
102− return m_loaded;
103−}
104−
105−void Lenses::onLensAdded(const unity::dash::Lens::Ptr& lens)
106−{
107− int index = m_lenses.count();
108− beginInsertRows(QModelIndex(), index, index);
109− addUnityLens(lens);
110− endInsertRows();
111−}
112−
113−void Lenses::onLensesLoaded()
114−{
115− /* FIXME: this is temporary code that is required on mobile to order
116− the lenses according to the design.
117− */
118− QStringList staticLenses;
119− staticLenses << "mockmusic.lens" << "people.lens" << "home.lens" << "applications.lens" << "mockvideos.lens";
120−
121− // not all the lenses are guaranteed to go into the model (only if their UnitCore counterparts exist);
122− // so build up a list of the valid ones, then add them later.
123− QList<unity::dash::Lens::Ptr> added_lenses;
124−
125− // add statically ordered lenses
126− Q_FOREACH(QString lensId, staticLenses) {
127− if (lensId == "home.lens") {
128− added_lenses << m_homeLens;
129− } else {
130− unity::dash::Lens::Ptr lens = m_unityLenses->GetLens(lensId.toStdString());
131− if (lens != NULL) {
132− added_lenses << lens;
133− }
134− }
135− }
136−
137− // add remaining lenses
138− unity::dash::Lenses::LensList lensesList = m_unityLenses->GetLenses();
139− for(auto it = lensesList.begin(); it != lensesList.end(); ++it) {
140− unity::dash::Lens::Ptr lens = (*it);
141− if (!staticLenses.contains(QString::fromStdString(lens->id))) {
142− added_lenses << lens;
143− }
144− }
145−
146− if (added_lenses.count() > 0) {
147− int index = rowCount();
148− beginInsertRows(QModelIndex(), index, index+added_lenses.count()-1);
149− Q_FOREACH(unity::dash::Lens::Ptr lens, added_lenses) {
150− addUnityLens(lens);
151− }
152− endInsertRows();
153− }
154−
155− m_loaded = true;
156− Q_EMIT loadedChanged(m_loaded);
157−
158− // listen to dynamically added lenses
159− m_homeLens->lens_added.connect(sigc::mem_fun(this, &Lenses::onLensAdded));
160−}
161−
162−void Lenses::onLensPropertyChanged()
163−{
164− QModelIndex lensIndex = index(m_lenses.indexOf(qobject_cast<Lens*>(sender())));
165− Q_EMIT dataChanged(lensIndex, lensIndex);
166−}
167−
168−void Lenses::addUnityLens(const unity::dash::Lens::Ptr& unity_lens)
169−{
170− Lens* lens = new Lens(this);
171− lens->setUnityLens(unity_lens);
172− /* DOCME */
173− QObject::connect(lens, SIGNAL(visibleChanged(bool)), this, SLOT(onLensPropertyChanged()));
174− m_lenses.append(lens);
175−}
176−
177−void Lenses::removeUnityLens(int index)
178−{
179− Lens* lens = m_lenses.takeAt(index);
180−
181− delete lens;
182−}
plugins/Unity/peoplepreviewdata.cppdeleted−438
@@ -1,438 +0,0 @@
1−/*
2− * Copyright (C) 2012 Canonical, Ltd.
3− *
4− * Authors:
5− * Guenter Schwann <guenter.schwann@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 "peoplepreviewdata.h"
21−
22−#include <QDebug>
23−
24−#include "lens.h"
25−
26−static void phoneAppend(QQmlListProperty<PeoplePhoneData> *property, PeoplePhoneData *val)
27−{
28− Q_UNUSED(val);
29− Q_UNUSED(property);
30−}
31−static PeoplePhoneData *phoneAt(QQmlListProperty<PeoplePhoneData> *property, int index)
32−{
33− PeoplePreviewData *d = static_cast<PeoplePreviewData*>(property->data);
34− return d->phoneNumberList().at(index);
35−}
36−static int phoneCount(QQmlListProperty<PeoplePhoneData> *property)
37−{
38− PeoplePreviewData *d = static_cast<PeoplePreviewData*>(property->data);
39− return d->phoneNumberList().count();
40−}
41−static void phoneClear(QQmlListProperty<PeoplePhoneData> *property)
42−{
43− Q_UNUSED(property);
44−}
45−
46−static void emailAppend(QQmlListProperty<PeopleAddressData> *property, PeopleAddressData *val)
47−{
48− Q_UNUSED(val);
49− Q_UNUSED(property);
50−}
51−static PeopleAddressData *emailAt(QQmlListProperty<PeopleAddressData> *property, int index)
52−{
53− PeoplePreviewData *d = static_cast<PeoplePreviewData*>(property->data);
54− return d->emailAddressesList().at(index);
55−}
56−static int emailCount(QQmlListProperty<PeopleAddressData> *property)
57−{
58− PeoplePreviewData *d = static_cast<PeoplePreviewData*>(property->data);
59− return d->emailAddressesList().count();
60−}
61−static void emailClear(QQmlListProperty<PeopleAddressData> *property)
62−{
63− Q_UNUSED(property);
64−}
65−
66−static void imAppend(QQmlListProperty<PeopleIMData> *property, PeopleIMData *val)
67−{
68− Q_UNUSED(val);
69− Q_UNUSED(property);
70−}
71−static PeopleIMData *imAt(QQmlListProperty<PeopleIMData> *property, int index)
72−{
73− PeoplePreviewData *d = static_cast<PeoplePreviewData*>(property->data);
74− return d->imAccountsList().at(index);
75−}
76−static int imCount(QQmlListProperty<PeopleIMData> *property)
77−{
78− PeoplePreviewData *d = static_cast<PeoplePreviewData*>(property->data);
79− return d->imAccountsList().count();
80−}
81−static void imClear(QQmlListProperty<PeopleIMData> *property)
82−{
83− Q_UNUSED(property);
84−}
85−
86−static void addressAppend(QQmlListProperty<PeopleAddressData> *property, PeopleAddressData *val)
87−{
88− Q_UNUSED(val);
89− Q_UNUSED(property);
90−}
91−static PeopleAddressData *addressAt(QQmlListProperty<PeopleAddressData> *property, int index)
92−{
93− PeoplePreviewData *d = static_cast<PeoplePreviewData*>(property->data);
94− return d->addressesList().at(index);
95−}
96−static int addressCount(QQmlListProperty<PeopleAddressData> *property)
97−{
98− PeoplePreviewData *d = static_cast<PeoplePreviewData*>(property->data);
99− return d->addressesList().count();
100−}
101−static void addressClear(QQmlListProperty<PeopleAddressData> *property)
102−{
103− Q_UNUSED(property);
104−}
105−
106−
107−using namespace unity;
108−
109−PeoplePreviewData::PeoplePreviewData(QObject *parent)
110−: QObject(parent)
111−, m_lens(0)
112−, m_ready(false)
113−{
114−}
115−
116−PeoplePreviewData::~PeoplePreviewData()
117−{
118− clearData();
119−}
120−
121−Lens *PeoplePreviewData::lens() const
122−{
123− return m_lens;
124−}
125−
126−void PeoplePreviewData::setLens(Lens *lens)
127−{
128− if (lens == m_lens)
129− return;
130−
131− setReady(false);
132−
133− if (m_lensConnection.connected())
134− m_lensConnection.disconnect();
135−
136− m_lens = lens;
137− m_lensConnection = m_lens->unityLens()->preview_ready.connect(
138− sigc::mem_fun(this, &PeoplePreviewData::setUnityPreview));
139− Q_EMIT lensChanged();
140−
141− if (!m_uri.isEmpty() && !m_lens)
142− getPeoplePreview();
143−}
144−
145−QString PeoplePreviewData::uri() const
146−{
147− return m_uri;
148−}
149−
150−void PeoplePreviewData::setUri(const QString &uri)
151−{
152− if (uri == m_uri)
153− return;
154−
155− setReady(false);
156−
157− m_uri = uri;
158− Q_EMIT uriChanged();
159− if (!m_uri.isEmpty() && m_lens)
160− getPeoplePreview();
161−}
162−
163−bool PeoplePreviewData::ready() const
164−{
165− return m_ready;
166−}
167−
168−void PeoplePreviewData::setReady(const bool &ready)
169−{
170− if (ready == m_ready)
171− return;
172−
173− m_ready = ready;
174− Q_EMIT readyChanged();
175−}
176−
177−QString PeoplePreviewData::renderName() const
178−{
179− if (!m_unityPreview)
180− return QLatin1String("");
181−
182− return QString::fromStdString(m_unityPreview->renderer_name());
183−}
184−
185−QString PeoplePreviewData::title() const
186−{
187− if (!m_unityPreview)
188− return QLatin1String("");
189−
190− return QString::fromStdString(m_unityPreview->title());
191−}
192−
193−QString PeoplePreviewData::subTitle() const
194−{
195− if (!m_unityPreview)
196− return QLatin1String("");
197−
198− return QString::fromStdString(m_unityPreview->subtitle());
199−}
200−
201−QString PeoplePreviewData::description() const
202−{
203− if (!m_unityPreview)
204− return QLatin1String("");
205−
206− return QString::fromStdString(m_unityPreview->description());
207−}
208−
209−QString PeoplePreviewData::imageSource() const
210−{
211− if (!m_unityPreview)
212− return QLatin1String("");
213−
214− return QString::fromStdString(m_unityPreview->image_source_uri());
215−}
216−
217−QQmlListProperty<PeoplePhoneData> PeoplePreviewData::phoneNumbers()
218−{
219− return QQmlListProperty<PeoplePhoneData> (this, this,
220− phoneAppend,
221− phoneCount,
222− phoneAt,
223− phoneClear);
224−}
225−
226−QQmlListProperty<PeopleAddressData> PeoplePreviewData::emailAddresses()
227−{
228− return QQmlListProperty<PeopleAddressData> (this, this,
229− emailAppend,
230− emailCount,
231− emailAt,
232− emailClear);
233−}
234−
235−QQmlListProperty<PeopleIMData> PeoplePreviewData::imAccounts()
236−{
237− return QQmlListProperty<PeopleIMData> (this, this,
238− imAppend,
239− imCount,
240− imAt,
241− imClear);
242−}
243−
244−QString PeoplePreviewData::displayName() const
245−{
246− if (!m_unityPreview)
247− return QLatin1String("");
248−
249− return QString::fromStdString(m_unityPreview->display_name());
250−}
251−
252−QString PeoplePreviewData::status() const
253−{
254− if (!m_unityPreview)
255− return QLatin1String("");
256−
257− return QString::fromStdString(m_unityPreview->status());
258−}
259−
260−QString PeoplePreviewData::statusTime() const
261−{
262− if (!m_unityPreview)
263− return QLatin1String("");
264−
265− return QString::fromStdString(m_unityPreview->status_time());
266−}
267−
268−QString PeoplePreviewData::statusService() const
269−{
270− if (!m_unityPreview)
271− return QLatin1String("");
272−
273− return QString::fromStdString(m_unityPreview->status_service());
274−}
275−
276−QString PeoplePreviewData::statusServiceIcon() const
277−{
278− if (!m_unityPreview)
279− return QLatin1String("");
280−
281− glib::Object<GIcon> icon = m_unityPreview->status_service_icon();
282− if (!icon)
283− return QLatin1String("");
284−
285− return QString(g_icon_to_string(icon));
286−}
287−
288−QString PeoplePreviewData::statusPostUri() const
289−{
290− if (!m_unityPreview)
291− return QLatin1String("");
292−
293− return QString::fromStdString(m_unityPreview->status_post_uri());
294−}
295−
296−QQmlListProperty<PeopleAddressData> PeoplePreviewData::addresses()
297−{
298− return QQmlListProperty<PeopleAddressData> (this, this,
299− addressAppend,
300− addressCount,
301− addressAt,
302− addressClear);
303−}
304−
305−QString PeoplePreviewData::avatar() const
306−{
307− if (!m_unityPreview)
308− return QLatin1String("");
309−
310− glib::Object<GIcon> avatar = m_unityPreview->avatar();
311− if (!avatar)
312− return QLatin1String("");
313−
314− return QString(g_icon_to_string(avatar));
315−}
316−
317−void PeoplePreviewData::getPeoplePreview()
318−{
319− m_lens->unityLens()->Preview(m_uri.toStdString());
320−}
321−
322−void PeoplePreviewData::setUnityPreview(std::string const& uri, dash::Preview::Ptr const& preview)
323−{
324− if (uri != m_uri.toStdString())
325− return;
326−
327− dash::PeoplePreview::Ptr peoplePtr = std::dynamic_pointer_cast<dash::PeoplePreview>(preview);
328− if (peoplePtr == nullptr) {
329− qWarning() << "Backend returned a dash::Preview that isn't a dash::PeoplePreview";
330− Q_EMIT error();
331− return;
332− }
333−
334− clearData();
335− m_unityPreview = peoplePtr;
336− getPhoneData();
337− getEmailAddresses();
338− getImAccounts();
339− getAddresses();
340−
341− Q_EMIT renderNameChanged();
342− Q_EMIT titleChanged();
343− Q_EMIT subTitleChanged();
344− Q_EMIT descriptionChanged();
345− Q_EMIT imageSourceChanged();
346− Q_EMIT phoneNumbersChanged();
347− Q_EMIT emailAddressesChanged();
348− Q_EMIT imAccountsChanged();
349− Q_EMIT displayNameChanged();
350− Q_EMIT statusChanged();
351− Q_EMIT statusTimeChanged();
352− Q_EMIT statusServiceChanged();
353− Q_EMIT addressesChanged();
354− Q_EMIT avatarChanged();
355−
356− setReady(true);
357−}
358−
359−void PeoplePreviewData::clearData()
360−{
361− while (!m_phoneList.empty()) {
362− PeoplePhoneData *phone = m_phoneList.takeLast();
363− delete phone;
364− }
365− while (!m_emailList.empty()) {
366− PeopleAddressData *email = m_emailList.takeLast();
367− delete email;
368− }
369− while (!m_imList.empty()) {
370− PeopleIMData *im = m_imList.takeLast();
371− delete im;
372− }
373− while (!m_addressList.empty()) {
374− PeopleAddressData *address = m_addressList.takeLast();
375− delete address;
376− }
377−}
378−
379−void PeoplePreviewData::getPhoneData()
380−{
381− dash::PeoplePreview::PhonePtrList uPhoneList;
382− uPhoneList = m_unityPreview->GetPhone();
383−
384− for (size_t i=0; i<uPhoneList.size(); ++i) {
385− PeoplePhoneData *phone = new PeoplePhoneData;
386− phone->m_type = QString::fromStdString(uPhoneList[i]->type);
387− phone->m_location = QString::fromStdString(uPhoneList[i]->location);
388− phone->m_number = QString::fromStdString(uPhoneList[i]->number);
389− m_phoneList.append(phone);
390− }
391−}
392−
393−void PeoplePreviewData::getEmailAddresses()
394−{
395− dash::PeoplePreview::EmailPtrList uEmailList;
396− uEmailList = m_unityPreview->GetEmail();
397−
398− for (size_t i=0; i<uEmailList.size(); ++i) {
399− PeopleAddressData *email = new PeopleAddressData;
400− email->m_type = QString::fromStdString(uEmailList[i]->type);
401− email->m_address = QString::fromStdString(uEmailList[i]->address);
402− m_emailList.append(email);
403− }
404−}
405−
406−void PeoplePreviewData::getImAccounts()
407−{
408− dash::PeoplePreview::IMAccountPtrList uIMList;
409− uIMList = m_unityPreview->GetIMAccount();
410−
411− for (size_t i=0; i<uIMList.size(); ++i) {
412− PeopleIMData *im = new PeopleIMData;
413− im->m_protocol = QString::fromStdString(uIMList[i]->protocol);
414− im->m_address = QString::fromStdString(uIMList[i]->address);
415− m_imList.append(im);
416− }
417−}
418−
419−void PeoplePreviewData::getAddresses()
420−{
421− dash::PeoplePreview::AddressPtrList uAddressList;
422− uAddressList = m_unityPreview->GetAddress();
423−
424− for (size_t i=0; i<uAddressList.size(); ++i) {
425− PeopleAddressData *address = new PeopleAddressData;
426− address->m_type = QString::fromStdString(uAddressList[i]->type);
427− address->m_address = QString::fromStdString(uAddressList[i]->address);
428− address->m_poBox = QString::fromStdString(uAddressList[i]->po_box);
429− address->m_extension = QString::fromStdString(uAddressList[i]->extension);
430− address->m_street = QString::fromStdString(uAddressList[i]->street);
431− address->m_locality = QString::fromStdString(uAddressList[i]->locality);
432− address->m_region = QString::fromStdString(uAddressList[i]->region);
433− address->m_postalCode = QString::fromStdString(uAddressList[i]->postal_code);
434− address->m_country = QString::fromStdString(uAddressList[i]->country);
435− address->m_addressFormat = QString::fromStdString(uAddressList[i]->address_format);
436− m_addressList.append(address);
437− }
438−}
plugins/Unity/peoplepreviewdata.hdeleted−251
@@ -1,251 +0,0 @@
1−/*
2− * Copyright (C) 2012 Canonical, Ltd.
3− *
4− * Authors:
5− * Guenter Schwann <guenter.schwann@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 PEOPLEPREVIEWDATA_H
21−#define PEOPLEPREVIEWDATA_H
22−
23−#include <QList>
24−#include <QObject>
25−#include <qqmllist.h>
26−#include <QString>
27−
28−// libunity-core
29−#include <UnityCore/PeoplePreview.h>
30−
31−#include <sigc++/connection.h>
32−
33−class Lens;
34−
35−/*!
36− * \brief The PeoplePhoneData class stores the data for one phone number
37− */
38−class PeoplePhoneData : public QObject
39−{
40− Q_OBJECT
41− Q_PROPERTY(QString type READ type NOTIFY typeChanged)
42− Q_PROPERTY(QString location READ location NOTIFY locationChanged)
43− Q_PROPERTY(QString number READ number NOTIFY numberChanged)
44−
45−Q_SIGNALS:
46− void typeChanged();
47− void locationChanged();
48− void numberChanged();
49−
50−public:
51− explicit PeoplePhoneData(QObject *parent = 0) : QObject(parent) {}
52− QString type() const { return m_type; }
53− QString location() const { return m_location; }
54− QString number() const { return m_number; }
55−
56−private:
57− QString m_type;
58− QString m_location;
59− QString m_number;
60− friend class PeoplePreviewData;
61−};
62−
63−/*!
64− * \brief The PeopleAddressData class stores the data for one single post/email address
65− */
66−class PeopleAddressData : public QObject
67−{
68− Q_OBJECT
69− Q_PROPERTY(QString type READ type NOTIFY typeChanged)
70− Q_PROPERTY(QString address READ address NOTIFY addressChanged)
71− Q_PROPERTY(QString poBox READ poBox NOTIFY poBoxChanged)
72− Q_PROPERTY(QString extension READ extension NOTIFY extensionChanged)
73− Q_PROPERTY(QString street READ street NOTIFY streetChanged)
74− Q_PROPERTY(QString locality READ locality NOTIFY localityChanged)
75− Q_PROPERTY(QString region READ region NOTIFY regionChanged)
76− Q_PROPERTY(QString postalCode READ postalCode NOTIFY postalCodeChanged)
77− Q_PROPERTY(QString country READ country NOTIFY countryChanged)
78− Q_PROPERTY(QString addressFormat READ addressFormat NOTIFY addressFormatChanged)
79−
80−Q_SIGNALS:
81− void typeChanged();
82− void addressChanged();
83− void poBoxChanged();
84− void extensionChanged();
85− void streetChanged();
86− void localityChanged();
87− void regionChanged();
88− void postalCodeChanged();
89− void countryChanged();
90− void addressFormatChanged();
91−
92−public:
93− explicit PeopleAddressData(QObject *parent = 0) : QObject(parent) {}
94− QString type() const { return m_type; }
95− QString address() const { return m_address; }
96− QString poBox() const { return m_poBox; }
97− QString extension() const { return m_extension; }
98− QString street() const { return m_street; }
99− QString locality() const { return m_locality; }
100− QString region() const { return m_region; }
101− QString postalCode() const { return m_postalCode; }
102− QString country() const { return m_country; }
103− QString addressFormat() const { return m_addressFormat; }
104−
105−private:
106− QString m_type;
107− QString m_address;
108− QString m_poBox;
109− QString m_extension;
110− QString m_street;
111− QString m_locality;
112− QString m_region;
113− QString m_postalCode;
114− QString m_country;
115− QString m_addressFormat;
116− friend class PeoplePreviewData;
117−};
118−
119−/*!
120− * \brief The PeopleIMData class stores the data for one single post/email address
121− */
122−class PeopleIMData : public QObject
123−{
124− Q_OBJECT
125− Q_PROPERTY(QString protocol READ protocol NOTIFY protocolChanged)
126− Q_PROPERTY(QString address READ address NOTIFY addressChanged)
127−
128−Q_SIGNALS:
129− void protocolChanged();
130− void addressChanged();
131−
132−public:
133− explicit PeopleIMData(QObject *parent = 0) : QObject(parent) {}
134− QString protocol() const { return m_protocol; }
135− QString address() const { return m_address; }
136−
137−private:
138− QString m_protocol;
139− QString m_address;
140− friend class PeoplePreviewData;
141−};
142−
143−
144−/*!
145− * \brief The PeoplePreviewData class providing information for one person
146− */
147−class PeoplePreviewData : public QObject
148−{
149− Q_OBJECT
150−
151− // These properties need to be set from QML
152− Q_PROPERTY(Lens* lens READ lens WRITE setLens NOTIFY lensChanged)
153− Q_PROPERTY(QString uri READ uri WRITE setUri NOTIFY uriChanged)
154− // Read only properties containing general Preview information
155− Q_PROPERTY(bool ready READ ready NOTIFY readyChanged)
156− Q_PROPERTY(QString renderName READ renderName NOTIFY renderNameChanged)
157− Q_PROPERTY(QString title READ title NOTIFY titleChanged)
158− Q_PROPERTY(QString subTitle READ subTitle NOTIFY subTitleChanged)
159− Q_PROPERTY(QString description READ description NOTIFY descriptionChanged)
160− Q_PROPERTY(QString imageSource READ imageSource NOTIFY imageSourceChanged)
161− // Read only properties containing PeoplePreview specific information
162− Q_PROPERTY(QString displayName READ displayName NOTIFY displayNameChanged)
163− Q_PROPERTY(QQmlListProperty<PeopleAddressData> emailAddresses READ emailAddresses NOTIFY emailAddressesChanged)
164− Q_PROPERTY(QQmlListProperty<PeoplePhoneData> phoneNumbers READ phoneNumbers NOTIFY phoneNumbersChanged)
165− Q_PROPERTY(QQmlListProperty<PeopleIMData> imAccounts READ imAccounts NOTIFY imAccountsChanged)
166− Q_PROPERTY(QString status READ status NOTIFY statusChanged)
167− Q_PROPERTY(QString statusTime READ statusTime NOTIFY statusTimeChanged)
168− Q_PROPERTY(QString statusService READ statusService NOTIFY statusServiceChanged)
169− Q_PROPERTY(QString statusServiceIcon READ statusServiceIcon NOTIFY statusServiceIconChanged)
170− Q_PROPERTY(QString statusPostUri READ statusPostUri NOTIFY statusPostUriChanged)
171− Q_PROPERTY(QQmlListProperty<PeopleAddressData> addresses READ addresses NOTIFY addressesChanged)
172− Q_PROPERTY(QString avatar READ avatar NOTIFY avatarChanged)
173−
174−public:
175− PeoplePreviewData(QObject *parent = 0);
176− ~PeoplePreviewData();
177−
178− void setUnityPeoplePreview(const unity::dash::Preview::Ptr& preview);
179− void setLens(Lens *lens);
180− void setUri(const QString &uri);
181−
182− Lens *lens() const;
183− QString uri() const;
184− bool ready() const;
185− QString renderName() const;
186− QString title() const;
187− QString subTitle() const;
188− QString description() const;
189− QString imageSource() const;
190− QString displayName() const;
191− QQmlListProperty<PeoplePhoneData> phoneNumbers();
192− QQmlListProperty<PeopleAddressData> emailAddresses();
193− QQmlListProperty<PeopleIMData> imAccounts();
194− QString status() const;
195− QString statusTime() const;
196− QString statusService() const;
197− QString statusServiceIcon() const;
198− QString statusPostUri() const;
199− QQmlListProperty<PeopleAddressData> addresses();
200− QString avatar() const;
201−
202− QList<PeoplePhoneData*> &phoneNumberList() { return m_phoneList; }
203− QList<PeopleAddressData*> &emailAddressesList() { return m_emailList; }
204− QList<PeopleIMData*> &imAccountsList() { return m_imList; }
205− QList<PeopleAddressData*> &addressesList() { return m_addressList; }
206−
207−Q_SIGNALS:
208− void lensChanged();
209− void uriChanged();
210− void readyChanged();
211− void renderNameChanged();
212− void titleChanged();
213− void subTitleChanged();
214− void descriptionChanged();
215− void imageSourceChanged();
216− void displayNameChanged();
217− void phoneNumbersChanged();
218− void emailAddressesChanged();
219− void imAccountsChanged();
220− void statusChanged();
221− void statusTimeChanged();
222− void statusServiceChanged();
223− void statusServiceIconChanged();
224− void statusPostUriChanged();
225− void addressesChanged();
226− void avatarChanged();
227− void error();
228−
229−private:
230− void setReady(const bool &ready);
231− void getPeoplePreview();
232− void setUnityPreview(std::string const& uri, unity::dash::Preview::Ptr const& preview);
233− void clearData();
234− void getPhoneData();
235− void getEmailAddresses();
236− void getImAccounts();
237− void getAddresses();
238−
239− Lens *m_lens;
240− sigc::connection m_lensConnection;
241− QString m_uri;
242− bool m_ready;
243− unity::dash::PeoplePreview::Ptr m_unityPreview;
244−
245− QList<PeoplePhoneData*> m_phoneList;
246− QList<PeopleAddressData*> m_addressList;
247− QList<PeopleIMData*> m_imList;
248− QList<PeopleAddressData*> m_emailList;
249−};
250−
251−#endif // PEOPLEPREVIEWDATA_H
plugins/Unity/plugin.cpp+4−9
@@ -24,11 +24,10 @@
2424#include "plugin.h"
2525
2626// local
27−#include "lens.h"
28−#include "lenses.h"
27+#include "scope.h"
28+#include "scopes.h"
2929#include "categories.h"
3030#include "categoryfilter.h"
31−#include "peoplepreviewdata.h"
3231#include "bottombarvisibilitycommunicatorshell.h"
3332#include "launchermodel.h"
3433
@@ -41,15 +40,11 @@ static const char* DBUS_SERVICE = "com.canonical.Shell.BottomBarVisibilityCommun
4140void UnityPlugin::registerTypes(const char *uri)
4241{
4342 Q_ASSERT(uri == QLatin1String("Unity"));
44− qmlRegisterType<Lens>(uri, 0, 1, "Lens");
45− qmlRegisterType<Lenses>(uri, 0, 1, "Lenses");
43+ qmlRegisterType<Scope>(uri, 0, 1, "Scope");
44+ qmlRegisterType<Scopes>(uri, 0, 1, "Scopes");
4645 qmlRegisterType<Categories>(uri, 0, 1, "Categories");
4746 qmlRegisterType<CategoryFilter>(uri, 0, 1, "CategoryFilter");
4847 qmlRegisterType<DeeListModel>(uri, 0, 1, "DeeListModel");
49− qmlRegisterType<PeoplePreviewData>(uri, 0, 1, "PeoplePreviewData");
50− qmlRegisterType<PeoplePhoneData>(uri, 0, 1, "PeoplePhoneData");
51− qmlRegisterType<PeopleAddressData>(uri, 0, 1, "PeopleAddressData");
52− qmlRegisterType<PeopleIMData>(uri, 0, 1, "PeopleIMData");
5348 qmlRegisterType<LauncherModel>(uri, 0, 1, "LauncherModel");
5449 qmlRegisterUncreatableType<LauncherItem>(uri, 0, 1, "LauncherItem", "Can't create new Launcher Items in QML. Get them from the LauncherModel.");
5550 qmlRegisterUncreatableType<BottomBarVisibilityCommunicatorShell>(uri, 0, 1, "BottomBarVisibilityCommunicatorShell", "Can't create BottomBarVisibilityCommunicatorShell");
plugins/Unity/scope.cppnew file+273
@@ -0,0 +1,273 @@
1+/*
2+ * Copyright (C) 2011 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Florian Boucault <florian.boucault@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+// Self
21+#include "scope.h"
22+#include "categories.h"
23+
24+// Qt
25+#include <QUrl>
26+#include <QDebug>
27+#include <QtGui/QDesktopServices>
28+
29+#include <libintl.h>
30+
31+Scope::Scope(QObject *parent) :
32+ QObject(parent)
33+{
34+ m_results = new DeeListModel(this);
35+ m_categories = new Categories(this);
36+
37+ m_categories->setResultModel(m_results);
38+}
39+
40+QString Scope::id() const
41+{
42+ return QString::fromStdString(m_unityScope->id());
43+}
44+
45+QString Scope::name() const
46+{
47+ return QString::fromStdString(m_unityScope->name());
48+}
49+
50+QString Scope::iconHint() const
51+{
52+ return QString::fromStdString(m_unityScope->icon_hint());
53+}
54+
55+QString Scope::description() const
56+{
57+ return QString::fromStdString(m_unityScope->description());
58+}
59+
60+QString Scope::searchHint() const
61+{
62+ return QString::fromStdString(m_unityScope->search_hint());
63+}
64+
65+bool Scope::visible() const
66+{
67+ return m_unityScope->visible();
68+}
69+
70+QString Scope::shortcut() const
71+{
72+ return QString::fromStdString(m_unityScope->shortcut());
73+}
74+
75+bool Scope::connected() const
76+{
77+ return m_unityScope->connected();
78+}
79+
80+DeeListModel* Scope::results() const
81+{
82+ return m_results;
83+}
84+
85+Categories* Scope::categories() const
86+{
87+ return m_categories;
88+}
89+
90+QString Scope::searchQuery() const
91+{
92+ return m_searchQuery;
93+}
94+
95+QString Scope::noResultsHint() const
96+{
97+ return m_noResultsHint;
98+}
99+
100+void Scope::setSearchQuery(const QString& search_query)
101+{
102+ /* Checking for m_searchQuery.isNull() which returns true only when the string
103+ has never been set is necessary because when search_query is the empty
104+ string ("") and m_searchQuery is the null string,
105+ search_query != m_searchQuery is still true.
106+ */
107+ if (m_searchQuery.isNull() || search_query != m_searchQuery) {
108+ m_searchQuery = search_query;
109+ m_unityScope->Search(search_query.toStdString(), sigc::mem_fun(this, &Scope::searchFinished));
110+ Q_EMIT searchQueryChanged();
111+ }
112+}
113+
114+void Scope::setNoResultsHint(const QString& hint) {
115+ if (hint != m_noResultsHint) {
116+ m_noResultsHint = hint;
117+ Q_EMIT noResultsHintChanged();
118+ }
119+}
120+
121+void Scope::activate(const QString& /*uri*/)
122+{
123+ // TODO:
124+ // we need to create unity::dash::LocalResult (see UnityCore/Result.h) and pass it to Activate;
125+ // this requires entire row from the model, so we need row index rather than uri.
126+ // m_unityScope->Activate(QByteArray::fromPercentEncoding(uri.toUtf8()).constData());
127+}
128+
129+void Scope::onActivated(unity::dash::LocalResult const& result, unity::dash::ScopeHandledType type, unity::glib::HintsMap const&)
130+{
131+ if (type == unity::dash::NOT_HANDLED) {
132+ fallbackActivate(QString::fromStdString(result.uri));
133+ }
134+}
135+
136+void Scope::fallbackActivate(const QString& uri)
137+{
138+ /* FIXME: stripping all content before the first column because for some
139+ reason the scopes give uri with junk content at their beginning.
140+ */
141+ QString tweakedUri = uri;
142+ int firstColumnAt = tweakedUri.indexOf(":");
143+ tweakedUri.remove(0, firstColumnAt+1);
144+
145+ /* Tries various methods to trigger a sensible action for the given 'uri'.
146+ If it has no understanding of the given scheme it falls back on asking
147+ Qt to open the uri.
148+ */
149+ QUrl url(tweakedUri);
150+ if (url.scheme() == "file") {
151+ /* Override the files place's default URI handler: we want the file
152+ manager to handle opening folders, not the dash.
153+
154+ Ref: https://bugs.launchpad.net/upicek/+bug/689667
155+ */
156+ QDesktopServices::openUrl(url);
157+ return;
158+ }
159+ if (url.scheme() == "application") {
160+ // TODO: implement application handling
161+ return;
162+ }
163+
164+ qWarning() << "FIXME: Possibly no handler for scheme: " << url.scheme();
165+ qWarning() << "Trying to open" << tweakedUri;
166+ /* Try our luck */
167+ QDesktopServices::openUrl(url);
168+}
169+
170+void Scope::setUnityScope(const unity::dash::Scope::Ptr& scope)
171+{
172+ m_unityScope = scope;
173+
174+ if (QString::fromStdString(m_unityScope->results()->swarm_name) == QString(":local")) {
175+ m_results->setModel(m_unityScope->results()->model());
176+ } else {
177+ m_results->setName(QString::fromStdString(m_unityScope->results()->swarm_name));
178+ }
179+
180+ if (QString::fromStdString(m_unityScope->categories()->swarm_name) == QString(":local")) {
181+ m_categories->setModel(m_unityScope->categories()->model());
182+ } else {
183+ m_categories->setName(QString::fromStdString(m_unityScope->categories()->swarm_name));
184+ }
185+
186+ /* Property change signals */
187+ m_unityScope->id.changed.connect(sigc::mem_fun(this, &Scope::idChanged));
188+ m_unityScope->name.changed.connect(sigc::mem_fun(this, &Scope::nameChanged));
189+ m_unityScope->icon_hint.changed.connect(sigc::mem_fun(this, &Scope::iconHintChanged));
190+ m_unityScope->description.changed.connect(sigc::mem_fun(this, &Scope::descriptionChanged));
191+ m_unityScope->search_hint.changed.connect(sigc::mem_fun(this, &Scope::searchHintChanged));
192+ m_unityScope->visible.changed.connect(sigc::mem_fun(this, &Scope::visibleChanged));
193+ m_unityScope->shortcut.changed.connect(sigc::mem_fun(this, &Scope::shortcutChanged));
194+ m_unityScope->connected.changed.connect(sigc::mem_fun(this, &Scope::connectedChanged));
195+ m_unityScope->results.changed.connect(sigc::mem_fun(this, &Scope::onResultsChanged));
196+ m_unityScope->results()->swarm_name.changed.connect(sigc::mem_fun(this, &Scope::onResultsSwarmNameChanged));
197+ m_unityScope->results()->model.changed.connect(sigc::mem_fun(this, &Scope::onResultsModelChanged));
198+ m_unityScope->categories()->model.changed.connect(sigc::mem_fun(this, &Scope::onCategoriesModelChanged));
199+ m_unityScope->categories.changed.connect(sigc::mem_fun(this, &Scope::onCategoriesChanged));
200+ m_unityScope->categories()->swarm_name.changed.connect(sigc::mem_fun(this, &Scope::onCategoriesSwarmNameChanged));
201+ /* Signals forwarding */
202+ connect(this, SIGNAL(searchFinished(const std::string &, unity::glib::HintsMap const &, unity::glib::Error const &)), SLOT(onSearchFinished(const std::string &, unity::glib::HintsMap const &)));
203+
204+ /* FIXME: signal should be forwarded instead of calling the handler directly */
205+ m_unityScope->activated.connect(sigc::mem_fun(this, &Scope::onActivated));
206+
207+ /* Synchronize local states with m_unityScope right now and whenever
208+ m_unityScope becomes connected */
209+ /* FIXME: should emit change notification signals for all properties */
210+ connect(this, SIGNAL(connectedChanged(bool)), SLOT(synchronizeStates()));
211+ synchronizeStates();
212+}
213+
214+unity::dash::Scope::Ptr Scope::unityScope() const
215+{
216+ return m_unityScope;
217+}
218+
219+void Scope::synchronizeStates()
220+{
221+ if (connected()) {
222+ /* Forward local states to m_unityScope */
223+ if (!m_searchQuery.isNull()) {
224+ m_unityScope->Search(m_searchQuery.toStdString());
225+ }
226+ }
227+}
228+
229+void Scope::onResultsSwarmNameChanged(const std::string& /* swarm_name */)
230+{
231+ m_results->setName(QString::fromStdString(m_unityScope->results()->swarm_name));
232+}
233+
234+void Scope::onResultsChanged(const unity::dash::Results::Ptr& /* results */)
235+{
236+ m_results->setName(QString::fromStdString(m_unityScope->results()->swarm_name));
237+}
238+
239+void Scope::onResultsModelChanged(unity::glib::Object<DeeModel> /* model */)
240+{
241+ m_results->setModel(m_unityScope->results()->model());
242+}
243+
244+void Scope::onCategoriesSwarmNameChanged(const std::string& /* swarm_name */)
245+{
246+ m_categories->setName(QString::fromStdString(m_unityScope->categories()->swarm_name));
247+}
248+
249+void Scope::onCategoriesChanged(const unity::dash::Categories::Ptr& /* categories */)
250+{
251+ m_categories->setName(QString::fromStdString(m_unityScope->categories()->swarm_name));
252+}
253+
254+void Scope::onCategoriesModelChanged(unity::glib::Object<DeeModel> model)
255+{
256+ m_categories->setModel(model);
257+}
258+
259+void Scope::onSearchFinished(const std::string& /* query */, unity::glib::HintsMap const &hints)
260+{
261+ QString hint;
262+
263+ if (!m_unityScope->results()->count()) {
264+ unity::glib::HintsMap::const_iterator it = hints.find("no-results-hint");
265+ if (it != hints.end()) {
266+ hint = QString::fromStdString(it->second.GetString());
267+ } else {
268+ hint = QString::fromUtf8(dgettext("unity", "Sorry, there is nothing that matches your search."));
269+ }
270+ }
271+
272+ setNoResultsHint(hint);
273+}
plugins/Unity/lens.h → plugins/Unity/scope.hrenamed+16−44
@@ -17,8 +17,8 @@
1717 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1818 */
1919
20−#ifndef LENS_H
21−#define LENS_H
20+#ifndef SCOPE_H
21+#define SCOPE_H
2222
2323// Qt
2424#include <QObject>
@@ -26,76 +26,56 @@
2626#include <QMetaType>
2727
2828// libunity-core
29−#include <UnityCore/Lens.h>
29+#include <UnityCore/Scope.h>
30+#include <UnityCore/Results.h>
3031
3132// dee-qt
3233#include "deelistmodel.h"
3334
3435class Categories;
3536
36−class Lens : public QObject
37+class Scope : public QObject
3738{
3839 Q_OBJECT
39− Q_ENUMS(ViewType)
4040
4141 Q_PROPERTY(QString id READ id NOTIFY idChanged)
42− Q_PROPERTY(QString dbusName READ dbusName NOTIFY dbusNameChanged)
43− Q_PROPERTY(QString dbusPath READ dbusPath NOTIFY dbusPathChanged)
4442 Q_PROPERTY(QString name READ name NOTIFY nameChanged)
4543 Q_PROPERTY(QString iconHint READ iconHint NOTIFY iconHintChanged)
4644 Q_PROPERTY(QString description READ description NOTIFY descriptionChanged)
4745 Q_PROPERTY(QString searchHint READ searchHint NOTIFY searchHintChanged)
4846 Q_PROPERTY(bool visible READ visible NOTIFY visibleChanged)
49− Q_PROPERTY(bool searchInGlobal READ searchInGlobal NOTIFY searchInGlobalChanged)
5047 Q_PROPERTY(QString shortcut READ shortcut NOTIFY shortcutChanged)
5148 Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged)
5249 Q_PROPERTY(DeeListModel* results READ results NOTIFY resultsChanged)
53− Q_PROPERTY(DeeListModel* globalResults READ globalResults NOTIFY globalResultsChanged)
5450 Q_PROPERTY(Categories* categories READ categories NOTIFY categoriesChanged)
55− Q_PROPERTY(ViewType viewType READ viewType WRITE setViewType NOTIFY viewTypeChanged)
5651
5752 Q_PROPERTY(QString searchQuery READ searchQuery WRITE setSearchQuery NOTIFY searchQueryChanged)
58− Q_PROPERTY(QString globalSearchQuery READ globalSearchQuery WRITE setGlobalSearchQuery NOTIFY globalSearchQueryChanged)
5953 Q_PROPERTY(QString noResultsHint READ noResultsHint WRITE setNoResultsHint NOTIFY noResultsHintChanged)
6054
6155public:
62− explicit Lens(QObject *parent = 0);
63−
64− enum ViewType {
65− Hidden,
66− HomeView,
67− LensView
68− };
56+ explicit Scope(QObject *parent = 0);
6957
7058 /* getters */
7159 QString id() const;
72− QString dbusName() const;
73− QString dbusPath() const;
7460 QString name() const;
7561 QString iconHint() const;
7662 QString description() const;
7763 QString searchHint() const;
7864 bool visible() const;
79− bool searchInGlobal() const;
8065 QString shortcut() const;
8166 bool connected() const;
8267 DeeListModel* results() const;
83− DeeListModel* globalResults() const;
8468 Categories* categories() const;
85− ViewType viewType() const;
8669 QString searchQuery() const;
87− QString globalSearchQuery() const;
8870 QString noResultsHint() const;
8971
9072 /* setters */
91− void setViewType(const ViewType& viewType);
9273 void setSearchQuery(const QString& search_query);
93− void setGlobalSearchQuery(const QString& search_query);
9474 void setNoResultsHint(const QString& hint);
9575
9676 Q_INVOKABLE void activate(const QString& uri);
97− void setUnityLens(const unity::dash::Lens::Ptr& lens);
98− unity::dash::Lens::Ptr unityLens() const;
77+ void setUnityScope(const unity::dash::Scope::Ptr& scope);
78+ unity::dash::Scope::Ptr unityScope() const;
9979
10080Q_SIGNALS:
10181 void idChanged(const std::string&);
@@ -106,44 +86,36 @@ Q_SIGNALS:
10686 void descriptionChanged(const std::string&);
10787 void searchHintChanged(const std::string&);
10888 void visibleChanged(bool);
109− void searchInGlobalChanged(bool);
11089 void shortcutChanged(const std::string&);
11190 void connectedChanged(bool);
11291 void resultsChanged();
113− void globalResultsChanged();
11492 void categoriesChanged();
115− void viewTypeChanged(ViewType);
116− void searchFinished(unity::dash::Lens::Hints const&, unity::glib::Error const&);
117− void globalSearchFinished(unity::dash::Lens::Hints const&, unity::glib::Error const&);
93+ void searchFinished(const std::string&, unity::glib::HintsMap const&, unity::glib::Error const&);
11894 void searchQueryChanged();
119− void globalSearchQueryChanged();
12095 void noResultsHintChanged();
12196
12297private Q_SLOTS:
12398 void synchronizeStates();
124− void onSearchFinished(unity::dash::Lens::Hints const &);
99+ void onSearchFinished(const std::string &, unity::glib::HintsMap const &);
125100
126101private:
127102 void onResultsSwarmNameChanged(const std::string&);
128103 void onResultsChanged(const unity::dash::Results::Ptr&);
129− void onGlobalResultsSwarmNameChanged(const std::string&);
130− void onGlobalResultsChanged(const unity::dash::Results::Ptr&);
104+ void onResultsModelChanged(unity::glib::Object<DeeModel>);
131105 void onCategoriesSwarmNameChanged(const std::string&);
106+ void onCategoriesModelChanged(unity::glib::Object<DeeModel>);
132107 void onCategoriesChanged(const unity::dash::Categories::Ptr&);
133− void onViewTypeChanged(unity::dash::ViewType);
134108
135− void onActivated(std::string const& uri, unity::dash::HandledType type, unity::dash::Lens::Hints const&);
109+ void onActivated(unity::dash::LocalResult const& result, unity::dash::ScopeHandledType type, unity::glib::HintsMap const&);
136110 void fallbackActivate(const QString& uri);
137111
138− unity::dash::Lens::Ptr m_unityLens;
112+ unity::dash::Scope::Ptr m_unityScope;
139113 DeeListModel* m_results;
140− DeeListModel* m_globalResults;
141114 Categories* m_categories;
142115 QString m_searchQuery;
143− QString m_globalSearchQuery;
144116 QString m_noResultsHint;
145117};
146118
147−Q_DECLARE_METATYPE(Lens*)
119+Q_DECLARE_METATYPE(Scope*)
148120
149−#endif // LENS_H
121+#endif // SCOPE_H
plugins/Unity/scopes.cppnew file+176
@@ -0,0 +1,176 @@
1+/*
2+ * Copyright (C) 2011 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Florian Boucault <florian.boucault@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+// Self
21+#include "scopes.h"
22+
23+// Local
24+#include "scope.h"
25+
26+// Qt
27+#include <QDebug>
28+#include <QtCore/QStringList>
29+#include <QtGui/QKeySequence>
30+
31+Scopes::Scopes(QObject *parent)
32+ : QAbstractListModel(parent)
33+ , m_unityScopes(std::make_shared<unity::dash::GSettingsScopes>())
34+ , m_loaded(false)
35+{
36+ m_roles[Scopes::RoleScope] = "scope";
37+ m_roles[Scopes::RoleId] = "id";
38+ m_roles[Scopes::RoleVisible] = "visible";
39+
40+ m_unityScopes->scope_added.connect(sigc::mem_fun(this, &Scopes::onScopeAdded));
41+ m_unityScopes->scope_removed.connect(sigc::mem_fun(this, &Scopes::onScopeRemoved));
42+ m_unityScopes->scopes_reordered.connect(sigc::mem_fun(this, &Scopes::onScopesReordered));
43+ m_unityScopes->LoadScopes();
44+}
45+
46+QHash<int, QByteArray> Scopes::roleNames() const
47+{
48+ return m_roles;
49+}
50+
51+int Scopes::rowCount(const QModelIndex& parent) const
52+{
53+ Q_UNUSED(parent)
54+
55+ return m_scopes.count();
56+}
57+
58+QVariant Scopes::data(const QModelIndex& index, int role) const
59+{
60+ Q_UNUSED(role)
61+
62+ if (!index.isValid()) {
63+ return QVariant();
64+ }
65+
66+ Scope* scope = m_scopes.at(index.row());
67+
68+ if (role == Scopes::RoleScope) {
69+ return QVariant::fromValue(scope);
70+ } else if (role == Scopes::RoleId) {
71+ return QVariant::fromValue(scope->id());
72+ } else if (role == Scopes::RoleVisible) {
73+ return QVariant::fromValue(scope->visible());
74+ } else {
75+ return QVariant();
76+ }
77+}
78+
79+QVariant Scopes::get(int row) const
80+{
81+ return data(QAbstractListModel::index(row), 0);
82+}
83+
84+QVariant Scopes::get(const QString& scope_id) const
85+{
86+ Q_FOREACH(Scope* scope, m_scopes) {
87+ if (scope->id() == scope_id) {
88+ return QVariant::fromValue(scope);
89+ }
90+ }
91+
92+ return QVariant();
93+}
94+
95+bool Scopes::loaded() const
96+{
97+ return m_loaded;
98+}
99+
100+void Scopes::onScopeAdded(const unity::dash::Scope::Ptr& scope, int /*position*/)
101+{
102+ int index = m_scopes.count();
103+ beginInsertRows(QModelIndex(), index, index);
104+ addUnityScope(scope);
105+ endInsertRows();
106+
107+ // FIXME: do only once after all loaded?
108+ m_loaded = true;
109+ Q_EMIT loadedChanged(m_loaded);
110+}
111+
112+void Scopes::onScopesLoaded()
113+{
114+}
115+
116+void Scopes::onScopeRemoved(const unity::dash::Scope::Ptr& scope)
117+{
118+ auto id = QString::fromStdString(scope->id);
119+ auto index = findScopeById(id);
120+ if (index >= 0) {
121+ beginRemoveRows(QModelIndex(), index, index);
122+ removeUnityScope(index);
123+ endRemoveRows();
124+
125+ Q_EMIT scopeRemoved(id, index);
126+ }
127+}
128+
129+void Scopes::onScopesReordered(const unity::dash::Scopes::ScopeList& scopes)
130+{
131+ // FIXME Should use beginMoveRows()/endMoveRows() to not recreate the UI for every scope.
132+ beginResetModel();
133+
134+ // remove existing scopes
135+ for (auto i=m_scopes.count()-1; i>=0; i--) {
136+ removeUnityScope(i);
137+ }
138+
139+ // re-create scopes
140+ for (uint i=0; i<scopes.size(); i++) {
141+ addUnityScope(scopes[i]);
142+ }
143+ endResetModel();
144+}
145+
146+void Scopes::onScopePropertyChanged()
147+{
148+ QModelIndex scopeIndex = index(m_scopes.indexOf(qobject_cast<Scope*>(sender())));
149+ Q_EMIT dataChanged(scopeIndex, scopeIndex);
150+}
151+
152+void Scopes::addUnityScope(const unity::dash::Scope::Ptr& unity_scope)
153+{
154+ Scope* scope = new Scope(this);
155+ scope->setUnityScope(unity_scope);
156+ /* DOCME */
157+ QObject::connect(scope, SIGNAL(visibleChanged(bool)), this, SLOT(onScopePropertyChanged()));
158+ m_scopes.append(scope);
159+}
160+
161+void Scopes::removeUnityScope(int index)
162+{
163+ Scope* scope = m_scopes.takeAt(index);
164+
165+ delete scope;
166+}
167+
168+int Scopes::findScopeById(const QString& scope_id)
169+{
170+ for (int i=0; i<m_scopes.count(); i++) {
171+ if (m_scopes[i]->id() == scope_id) {
172+ return i;
173+ }
174+ }
175+ return -1;
176+}
plugins/Unity/lenses.h → plugins/Unity/scopes.hrenamed+25−21
@@ -17,29 +17,29 @@
1717 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1818 */
1919
20−#ifndef LENSES_H
21−#define LENSES_H
20+#ifndef SCOPES_H
21+#define SCOPES_H
2222
2323// Qt
2424#include <QAbstractListModel>
2525#include <QList>
2626
2727// libunity-core
28−#include <UnityCore/Lens.h>
29−#include <UnityCore/HomeLens.h>
28+#include <UnityCore/Scope.h>
29+#include <UnityCore/GSettingsScopes.h>
3030
3131namespace unity
3232{
3333namespace dash
3434{
35−class Lenses;
35+class Scopes;
3636}
3737}
3838
3939class Hotkey;
40−class Lens;
40+class Scope;
4141
42−class Lenses : public QAbstractListModel
42+class Scopes : public QAbstractListModel
4343{
4444 Q_OBJECT
4545
@@ -48,11 +48,11 @@ class Lenses : public QAbstractListModel
4848 Q_PROPERTY(bool loaded READ loaded NOTIFY loadedChanged)
4949
5050public:
51− explicit Lenses(QObject *parent = 0);
52− ~Lenses() = default;
51+ explicit Scopes(QObject *parent = 0);
52+ ~Scopes() = default;
5353
5454 enum Roles {
55− RoleLens,
55+ RoleScope,
5656 RoleId,
5757 RoleVisible
5858 };
@@ -61,30 +61,34 @@ public:
6161 Q_INVOKABLE int rowCount(const QModelIndex& parent = QModelIndex()) const;
6262
6363 Q_INVOKABLE QVariant get(int row) const;
64− Q_INVOKABLE QVariant get(const QString& lens_id) const;
64+ Q_INVOKABLE QVariant get(const QString& scope_id) const;
6565
6666 QHash<int, QByteArray> roleNames() const;
6767
6868 bool loaded() const;
6969
7070Q_SIGNALS:
71− void activateLensRequested(const QString& lens_id);
71+ void activateScopeRequested(const QString& scope_id);
7272 void loadedChanged(bool loaded);
73+ void scopeRemoved(const QString& scope_id, int index);
7374
7475private Q_SLOTS:
75− void onLensAdded(const unity::dash::Lens::Ptr& lens);
76− void onLensesLoaded();
77− void onLensPropertyChanged();
76+ void onScopesLoaded();
77+ void onScopeAdded(const unity::dash::Scope::Ptr& scope, int position);
78+ void onScopeRemoved(const unity::dash::Scope::Ptr& scope);
79+ void onScopesReordered(const unity::dash::Scopes::ScopeList& scopes);
80+ void onScopePropertyChanged();
7881
7982private:
80− unity::dash::Lenses::Ptr m_unityLenses;
81− unity::dash::HomeLens::Ptr m_homeLens;
82− QList<Lens*> m_lenses;
83+ unity::dash::GSettingsScopesReader::Ptr m_scopesReader;
84+ unity::dash::Scopes::Ptr m_unityScopes;
85+ QList<Scope*> m_scopes;
8386 QHash<int, QByteArray> m_roles;
8487 bool m_loaded;
8588
86− void addUnityLens(const unity::dash::Lens::Ptr& unity_lens);
87− void removeUnityLens(int index);
89+ void addUnityScope(const unity::dash::Scope::Ptr& unity_scope);
90+ void removeUnityScope(int index);
91+ int findScopeById(const QString& scope_id);
8892};
8993
90−#endif // LENSES_H
94+#endif // SCOPES_H
po/unity8.pot+9−36
@@ -109,27 +109,19 @@ msgstr ""
109109msgid "Apps"
110110msgstr ""
111111
112−#: Dash/DashHome.qml:43
112+#: Dash/DashHome.qml:40
113113msgid "Frequent Apps"
114114msgstr ""
115115
116−#: Dash/DashHome.qml:46
117−msgid "Favourite People"
118−msgstr ""
119−
120−#: Dash/DashHome.qml:49
121−msgid "People Recently in Touch"
122−msgstr ""
123−
124−#: Dash/DashHome.qml:52
116+#: Dash/DashHome.qml:43
125117msgid "Recent Music"
126118msgstr ""
127119
128−#: Dash/DashHome.qml:55
120+#: Dash/DashHome.qml:46
129121msgid "Videos Popular Online"
130122msgstr ""
131123
132−#: Dash/DashHome.qml:197 plugins/Unity/lenses.cpp:38
124+#: Dash/DashHome.qml:175
133125msgid "Home"
134126msgstr ""
135127
@@ -153,26 +145,6 @@ msgstr ""
153145msgid "Music"
154146msgstr ""
155147
156−#: Dash/DashPeople.qml:31
157−msgid "Favourites"
158−msgstr ""
159−
160−#: Dash/DashPeople.qml:32
161−msgid "Recently in touch"
162−msgstr ""
163−
164−#: Dash/DashPeople.qml:33
165−msgid "New Contacts"
166−msgstr ""
167−
168−#: Dash/DashPeople.qml:34
169−msgid "A-Z"
170−msgstr ""
171−
172−#: Dash/DashPeople.qml:123
173−msgid "People"
174−msgstr ""
175−
176148#: Dash/DashVideos.qml:31
177149msgid "Popular Online"
178150msgstr ""
@@ -234,16 +206,17 @@ msgstr ""
234206msgid "Flight mode"
235207msgstr ""
236208
237−#: Panel/SearchIndicator.qml:26 plugins/Unity/lenses.cpp:40
209+#: Panel/SearchIndicator.qml:26
238210msgid "Search"
239211msgstr ""
240212
241−#: plugins/Unity/lens.cpp:333
213+#: plugins/Unity/scope.cpp:268
242214msgid "Sorry, there is nothing that matches your search."
243215msgstr ""
244216
245−#: plugins/Unity/lenses.cpp:39
246−msgid "Home screen"
217+#: Shell.qml:380
218+#, qt-format
219+msgid "Please enter %1:"
247220msgstr ""
248221
249222#: Shell.qml:380
tests/autopilot/unity8/tests/helpers.py+1−1
@@ -71,7 +71,7 @@ class TestShellHelpers(object):
7171 self.touch.drag(start_x, start_y, stop_x, stop_y)
7272
7373 # Because the shell loads up lots of stuff, unlocking the greeter can
74− # be a bit stuttery while lenses are still consuming all resources.
74+ # be a bit stuttery while scopes are still consuming all resources.
7575 # Give it another (max retries) chance
7676 try:
7777 self.assertThat(greeter.created, Eventually(Equals(False)))
tests/autopilot/unity8/tests/testhud.py+1−1
@@ -73,7 +73,7 @@ class TestHud(ShellTestCase, TestShellHelpers):
7373 super(TestHud, self).setUp("%sx%s" % (self.app_width / divisor, self.app_height / divisor), "%s" % (self.grid_unit_px / divisor))
7474
7575 dash = self.main_window.get_dash()
76− self.assertThat(dash.showLensOnLoaded, Eventually(Equals(""), timeout=30))
76+ self.assertThat(dash.showScopeOnLoaded, Eventually(Equals(""), timeout=30))
7777
7878 def test_show_hud(self):
7979 hud = self.main_window.get_hud()
tests/autopilot/unity8/tests/testlockscreen.py+1−1
@@ -71,7 +71,7 @@ class TestLockscreens(ShellTestCase, TestShellHelpers):
7171 super(TestLockscreens, self).setUp("%sx%s" % (self.app_width / divisor, self.app_height / divisor), "%s" % (self.grid_unit_px / divisor))
7272
7373 dash = self.main_window.get_dash()
74− self.assertThat(dash.showLensOnLoaded, Eventually(Equals(""), timeout=30))
74+ self.assertThat(dash.showScopeOnLoaded, Eventually(Equals(""), timeout=30))
7575
7676 def test_unlock(self):
7777 self.unlock_greeter()
tests/qmltests/CMakeLists.txt+2−4
@@ -41,13 +41,11 @@ add_qml_test(Dash Dash IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAUL
4141add_qml_test(Dash DashBar IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${CMAKE_CURRENT_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
4242add_qml_test(Dash DashContent IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS})
4343add_qml_test(Dash DashPreview)
44−add_qml_test(Dash GenericLensView IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
45−add_qml_test(Dash LensView IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${CMAKE_CURRENT_BINARY_DIR}/plugins)
46−add_qml_test(Dash PeoplePreview)
44+add_qml_test(Dash GenericScopeView IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
45+add_qml_test(Dash ScopeView IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${CMAKE_CURRENT_BINARY_DIR}/plugins)
4746add_qml_test(Dash FilterGrids IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins ${CMAKE_CURRENT_SOURCE_DIR}/plugins
4847 ${CMAKE_BINARY_DIR}/tests/mocks)
4948add_qml_test(Dash/Apps RunningApplicationsGrid IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
50−add_qml_test(Dash/People PeopleFilterGrid IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${CMAKE_CURRENT_SOURCE_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
5149add_qml_test(Greeter Lockscreen IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins ${CMAKE_BINARY_DIR}/tests/mocks
5250 PROPERTIES ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full")
5351add_qml_test(Greeter Tablet IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins ${CMAKE_BINARY_DIR}/tests/mocks
tests/qmltests/Dash/People/tst_PeopleFilterGrid.qmldeleted−154
@@ -1,154 +0,0 @@
1−/*
2− * Copyright 2013 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import QtTest 1.0
19−import ".."
20−import "../.."
21−import "../../../../Dash/People"
22−import Ubuntu.Components 0.1
23−import Unity.Test 0.1 as UT
24−
25−Item {
26− id: root
27− width: units.gu(120)
28− height: units.gu(40)
29−
30− PeopleFilterGrid {
31− id: peopleFilterGrid
32− anchors.fill: parent
33− model: mockModel
34− }
35−
36− SignalSpy {
37− id: signalSpy
38− target: peopleFilterGrid
39− signalName: "clicked"
40− }
41−
42− ListModel {
43− id: mockModel
44−
45− ListElement {
46− column_0: 'user://001'
47− column_1: "gtk-apply"
48− column_2: ""
49− column_3: ""
50− column_4: "User 1"
51− column_5: "Text 1"
52− }
53−
54− ListElement {
55− column_0: 'user://002'
56− column_1: "gtk-apply"
57− column_2: ""
58− column_3: ""
59− column_4: "User 2"
60− column_5: "Text 2"
61− }
62−
63− ListElement {
64− column_0: 'user://003'
65− column_1: "gtk-apply"
66− column_2: ""
67− column_3: ""
68− column_4: "User 3"
69− column_5: "Text 3"
70− }
71−
72− ListElement {
73− column_0: 'user://004'
74− column_1: "gtk-apply"
75− column_2: ""
76− column_3: ""
77− column_4: "User 4"
78− column_5: "Text 4"
79− }
80−
81− ListElement {
82− column_0: 'user://005'
83− column_1: "gtk-apply"
84− column_2: ""
85− column_3: ""
86− column_4: "User 5"
87− column_5: "Text 5"
88− }
89−
90− }
91−
92− UT.UnityTestCase {
93− id: testCase
94− name: "DashPeopleFilterGrid"
95− when: windowShown
96−
97− function init() {
98− }
99−
100− function test_clickCell_data() {
101− return [
102− {
103− x: peopleFilterGrid.minimumHorizontalSpacing+peopleFilterGrid.cellWidth/2,
104− y: peopleFilterGrid.verticalSpacing+peopleFilterGrid.cellHeight/2,
105− index: 0,
106− uri: "user://001"
107− },
108− {
109− x: 2*peopleFilterGrid.minimumHorizontalSpacing+peopleFilterGrid.cellWidth+peopleFilterGrid.cellWidth/2,
110− y: peopleFilterGrid.verticalSpacing+peopleFilterGrid.cellHeight/2,
111− index: 1,
112− uri: "user://002"
113− },
114− {
115− x: 3*peopleFilterGrid.minimumHorizontalSpacing+2*peopleFilterGrid.cellWidth+peopleFilterGrid.cellWidth/2,
116− y: peopleFilterGrid.verticalSpacing+peopleFilterGrid.cellHeight/2,
117− index: 2,
118− uri: "user://003"
119− },
120− {
121− x: peopleFilterGrid.minimumHorizontalSpacing+peopleFilterGrid.cellWidth/2,
122− y: 2*peopleFilterGrid.verticalSpacing+peopleFilterGrid.cellHeight+peopleFilterGrid.cellHeight/2,
123− index: 3,
124− uri: "user://004"
125− },
126− {
127− x: 2*peopleFilterGrid.minimumHorizontalSpacing+peopleFilterGrid.cellWidth+peopleFilterGrid.cellWidth/2,
128− y: 2*peopleFilterGrid.verticalSpacing+peopleFilterGrid.cellHeight+peopleFilterGrid.cellHeight/2,
129− index: 4,
130− uri: "user://005"
131− },
132− ]
133− }
134−
135− function test_columns() {
136− compare(peopleFilterGrid.columns,3)
137− }
138−
139− function test_clickCell(data) {
140− tryCompare(peopleFilterGrid, "flicking", false)
141− tryCompare(peopleFilterGrid, "moving", false)
142− signalSpy.clear()
143− wait(peopleFilterGrid.pressDelay > 0 ? peopleFilterGrid.pressDelay : 5)
144− mouseClick(peopleFilterGrid, data.x, data.y)
145− tryCompare(peopleFilterGrid, "flicking", false)
146− tryCompare(peopleFilterGrid, "moving", false)
147− compare(signalSpy.count, 1)
148− compare(signalSpy.signalArguments.length, 1, "signalArguments.length != 1")
149− compare(signalSpy.signalArguments[0][0], data.index)
150− compare(signalSpy.signalArguments[0][1]["uri"], data.uri)
151− }
152−
153− }
154−}
tests/qmltests/Dash/qml/FakeLensView.qml → tests/qmltests/Dash/qml/FakeScopeView.qmlrenamed+9−9
@@ -18,8 +18,8 @@ import QtQuick 2.0
1818import Unity 0.1
1919
2020FocusScope {
21− id: fakeLensView
22− property Lens lens : null
21+ id: fakeScopeView
22+ property Scope scope : null
2323 property bool isCurrent : false
2424
2525 property ListModel searchHistory
@@ -31,18 +31,18 @@ FocusScope {
3131 property alias backColor : back.color
3232
3333 onEndReached: {
34− if (shell != undefined && shell.lensStatus != undefined) {
35− shell.lensStatus[lens.id].endReached++;
34+ if (shell != undefined && shell.scopeStatus != undefined) {
35+ shell.scopeStatus[scope.id].endReached++;
3636 }
3737 }
3838 onMovementStarted: {
39− if (shell != undefined && shell.lensStatus != undefined) {
40− shell.lensStatus[lens.id].movementStarted++;
39+ if (shell != undefined && shell.scopeStatus != undefined) {
40+ shell.scopeStatus[scope.id].movementStarted++;
4141 }
4242 }
4343 onPositionedAtBeginning: {
44− if (shell != undefined && shell.lensStatus != undefined) {
45− shell.lensStatus[lens.id].positionedAtBeginning++;
44+ if (shell != undefined && shell.scopeStatus != undefined) {
45+ shell.scopeStatus[scope.id].positionedAtBeginning++;
4646 }
4747 }
4848
@@ -68,7 +68,7 @@ FocusScope {
6868 ListView {
6969 id: listView
7070 anchors.fill: parent
71− model: lens ? lens.categories : null
71+ model: scope ? scope.categories : null
7272 orientation: ListView.Vertical
7373
7474 delegate: Column {
tests/qmltests/Dash/qml/fake_generic_lensView.qml → tests/qmltests/Dash/qml/fake_generic_scopeView.qmlrenamed+3−3
@@ -16,9 +16,9 @@
1616
1717import QtQuick 2.0
1818
19−FakeLensView {
20− id: fake_generic_lensView
21− objectName: "fake_generic_lensView"
19+FakeScopeView {
20+ id: fake_generic_scopeView
21+ objectName: "fake_generic_scopeView"
2222
2323 backColor: "#D0D0D0"
2424}
tests/qmltests/Dash/qml/fake_lensView1.qml → tests/qmltests/Dash/qml/fake_scopeView1.qmlrenamed+3−3
@@ -16,9 +16,9 @@
1616
1717import QtQuick 2.0
1818
19−FakeLensView {
20− id: fake_lensView1
21− objectName: "fake_lensView1"
19+FakeScopeView {
20+ id: fake_scopeView1
21+ objectName: "fake_scopeView1"
2222
2323 backColor: "#909090"
2424}
tests/qmltests/Dash/qml/fake_lensView2.qml → tests/qmltests/Dash/qml/fake_scopeView2.qmlrenamed+3−3
@@ -16,9 +16,9 @@
1616
1717import QtQuick 2.0
1818
19−FakeLensView {
20− id: fake_lensView2
21− objectName: "fake_lensView2"
19+FakeScopeView {
20+ id: fake_scopeView2
21+ objectName: "fake_scopeView2"
2222
2323 backColor: "#A0A0A0"
2424}
tests/qmltests/Dash/qml/fake_lensView3.qml → tests/qmltests/Dash/qml/fake_scopeView3.qmlrenamed+3−3
@@ -16,9 +16,9 @@
1616
1717import QtQuick 2.0
1818
19−FakeLensView {
20− id: fake_lensView3
21− objectName: "fake_lensView3"
19+FakeScopeView {
20+ id: fake_scopeView3
21+ objectName: "fake_scopeView3"
2222
2323 backColor: "#B0B0B0"
2424}
tests/qmltests/Dash/qml/fake_lensView4.qml → tests/qmltests/Dash/qml/fake_scopeView4.qmlrenamed+3−3
@@ -16,9 +16,9 @@
1616
1717import QtQuick 2.0
1818
19−FakeLensView {
20− id: fake_lensView4
21− objectName: "fake_lensView4"
19+FakeScopeView {
20+ id: fake_scopeView4
21+ objectName: "fake_scopeView4"
2222
2323 backColor: "#C0C0C0"
2424}
tests/qmltests/Dash/tst_Dash.qml+34−34
@@ -30,79 +30,79 @@ Item {
3030 Dash {
3131 id: dash
3232 anchors.fill: parent
33− showLensOnLoaded: "MockLens2"
33+ showScopeOnLoaded: "MockScope2"
3434 }
3535
36− LensDelegateMapper {
37− id: lensDelegateMapper
38− lensDelegateMapping: {
39− "MockLens1": "../tests/qmltests/Dash/qml/fake_lensView1.qml",
40− "MockLens2": "../tests/qmltests/Dash/qml/fake_lensView2.qml",
41− "MockLens3": "../tests/qmltests/Dash/qml/fake_lensView3.qml",
42− "MockLens4": "../tests/qmltests/Dash/qml/fake_lensView4.qml"
36+ ScopeDelegateMapper {
37+ id: scopeDelegateMapper
38+ scopeDelegateMapping: {
39+ "MockScope1": "../tests/qmltests/Dash/qml/fake_scopeView1.qml",
40+ "MockScope2": "../tests/qmltests/Dash/qml/fake_scopeView2.qml",
41+ "MockScope3": "../tests/qmltests/Dash/qml/fake_scopeView3.qml",
42+ "MockScope4": "../tests/qmltests/Dash/qml/fake_scopeView4.qml"
4343 }
44− genericLens: "../tests/qmltests/Dash/qml/fake_generic_lensView.qml"
44+ genericScope: "../tests/qmltests/Dash/qml/fake_generic_scopeView.qml"
4545 }
4646
4747 UT.UnityTestCase {
4848 name: "Dash"
4949 when: windowShown
5050
51− property var lenses
51+ property var scopes
5252
5353 Component.onCompleted: {
5454 var dashContent = findChild(dash, "dashContent");
55− dashContent.lensMapper = lensDelegateMapper;
56− lenses = dashContent.lenses;
55+ dashContent.scopeMapper = scopeDelegateMapper;
56+ scopes = dashContent.scopes;
5757 }
5858
5959 function init() {
60− // clear and reload the lenses.
61− lenses.clear();
60+ // clear and reload the scopes.
61+ scopes.clear();
6262 var dashContentList = findChild(dash, "dashContentList");
6363 verify(dashContentList != undefined);
6464 tryCompare(dashContentList, "count", 0);
65− lenses.load();
65+ scopes.load();
6666 }
6767
68− function get_lens_data() {
68+ function get_scope_data() {
6969 return [
70− { tag: "MockLens1", visualIndex: 0, shouldBeVisible: true },
71− { tag: "MockLens2", visualIndex: -1, shouldBeVisible: false },
72− { tag: "MockLens3", visualIndex: 1, shouldBeVisible: true },
73− { tag: "MockLens4", visualIndex: 2, shouldBeVisible: true },
74− { tag: "MockLens5", visualIndex: 3, shouldBeVisible: true },
70+ { tag: "MockScope1", visualIndex: 0, shouldBeVisible: true },
71+ { tag: "MockScope2", visualIndex: -1, shouldBeVisible: false },
72+ { tag: "MockScope3", visualIndex: 1, shouldBeVisible: true },
73+ { tag: "MockScope4", visualIndex: 2, shouldBeVisible: true },
74+ { tag: "MockScope5", visualIndex: 3, shouldBeVisible: true },
7575 ]
7676 }
7777
78− function test_set_current_lens_data() {
79− return get_lens_data()
78+ function test_set_current_scope_data() {
79+ return get_scope_data()
8080 }
8181
82− function test_set_current_lens(data) {
83− // wait for lenses to load
84− tryCompare(lenses, "loaded", true);
82+ function test_set_current_scope(data) {
83+ // wait for scopes to load
84+ tryCompare(scopes, "loaded", true);
8585
8686 var dashbar = findChild(dash, "dashbar");
8787 verify(dashbar != undefined)
8888 var dashContent = findChild(dash, "dashContent");
8989 var current_index = dashContent.currentIndex;
9090
91− dash.setCurrentLens(data.tag, true /* animate */, false /* reset */);
91+ dash.setCurrentScope(data.tag, true /* animate */, false /* reset */);
9292 compare(dashContent.currentIndex, data.shouldBeVisible ? data.visualIndex : current_index);
9393 compare(dashbar.currentIndex, data.shouldBeVisible ? data.visualIndex : current_index);
9494 }
9595
96− function test_show_lens_on_load_data() {
97− return get_lens_data()
96+ function test_show_scope_on_load_data() {
97+ return get_scope_data()
9898 }
9999
100− function test_show_lens_on_load(data) {
100+ function test_show_scope_on_load(data) {
101101 if (data.shouldBeVisible == false) {
102102 console.log("Not testing " + data.tag + ": not visible");
103103 return;
104104 }
105− dash.showLensOnLoaded = data.tag
105+ dash.showScopeOnLoaded = data.tag
106106
107107 var dashContentList = findChild(dash, "dashContentList");
108108 verify(dashContentList != undefined);
@@ -110,7 +110,7 @@ Item {
110110 }
111111
112112 function test_dash_bar_set_index_connection_data() {
113− return get_lens_data()
113+ return get_scope_data()
114114 }
115115
116116 function test_dash_bar_set_index_connection(data) {
@@ -118,8 +118,8 @@ Item {
118118 console.log("Not testing " + data.tag + ": not visible");
119119 return;
120120 }
121− // wait for lenses to load
122− tryCompare(lenses, "loaded", true);
121+ // wait for scopes to load
122+ tryCompare(scopes, "loaded", true);
123123
124124 var dashbar = findChild(dash, "dashbar");
125125 verify(dashbar != undefined)
tests/qmltests/Dash/tst_DashBar.qml+4−4
@@ -34,12 +34,12 @@ Item {
3434 right: parent.right
3535 bottom: parent.bottom
3636 }
37− model: lenses
37+ model: scopes
3838 onItemSelected: currentIndex = index
3939 }
4040
41− Lenses {
42− id: lenses
41+ Scopes {
42+ id: scopes
4343 }
4444
4545 SignalSpy {
@@ -50,7 +50,7 @@ Item {
5050
5151 UT.UnityTestCase {
5252 name: "DashBar"
53− when: lenses.loaded
53+ when: scopes.loaded
5454
5555 property alias model: dashBar.model
5656 property alias currentIndex: dashBar.currentIndex
tests/qmltests/Dash/tst_DashContent.qml+75−72
@@ -28,60 +28,60 @@ Item {
2828
2929 property ListModel searchHistory: ListModel {}
3030
31− property var lensStatus: {
32− 'MockLens1': { 'movementStarted': 0, 'positionedAtBeginning': 0 },
33− 'MockLens2': { 'movementStarted': 0, 'positionedAtBeginning': 0 },
34− 'MockLens3': { 'movementStarted': 0, 'positionedAtBeginning': 0 },
35− 'MockLens4': { 'movementStarted': 0, 'positionedAtBeginning': 0 },
36− 'MockLens5': { 'movementStarted': 0, 'positionedAtBeginning': 0 }
31+ property var scopeStatus: {
32+ 'MockScope1': { 'movementStarted': 0, 'positionedAtBeginning': 0 },
33+ 'MockScope2': { 'movementStarted': 0, 'positionedAtBeginning': 0 },
34+ 'MockScope3': { 'movementStarted': 0, 'positionedAtBeginning': 0 },
35+ 'MockScope4': { 'movementStarted': 0, 'positionedAtBeginning': 0 },
36+ 'MockScope5': { 'movementStarted': 0, 'positionedAtBeginning': 0 }
3737 }
3838
39− Lenses {
40− id: lensesModel
39+ Scopes {
40+ id: scopesModel
4141 }
4242
4343 DashContent {
4444 id: dashContent
4545 anchors.fill: parent
4646
47− model: lensesModel
48− lenses : lensesModel
47+ model: scopesModel
48+ scopes : scopesModel
4949
50− lensMapper : lensDelegateMapper
50+ scopeMapper : scopeDelegateMapper
5151 }
5252
53− LensDelegateMapper {
54− id: lensDelegateMapper
55− lensDelegateMapping: {
56− "MockLens1": "../tests/qmltests/Dash/qml/fake_lensView1.qml",
57− "MockLens2": "../tests/qmltests/Dash/qml/fake_lensView2.qml",
58− "MockLens3": "../tests/qmltests/Dash/qml/fake_lensView3.qml",
59− "MockLens4": "../tests/qmltests/Dash/qml/fake_lensView4.qml"
53+ ScopeDelegateMapper {
54+ id: scopeDelegateMapper
55+ scopeDelegateMapping: {
56+ "MockScope1": "../tests/qmltests/Dash/qml/fake_scopeView1.qml",
57+ "MockScope2": "../tests/qmltests/Dash/qml/fake_scopeView2.qml",
58+ "MockScope3": "../tests/qmltests/Dash/qml/fake_scopeView3.qml",
59+ "MockScope4": "../tests/qmltests/Dash/qml/fake_scopeView4.qml"
6060 }
61− genericLens: "../tests/qmltests/Dash/qml/fake_generic_lensView.qml"
61+ genericScope: "../tests/qmltests/Dash/qml/fake_generic_scopeView.qml"
6262 }
6363
64− function clear_lens_status() {
65− lensStatus["MockLens1"].movementStarted = 0;
66− lensStatus["MockLens1"].positionedAtBeginning = 0;
64+ function clear_scope_status() {
65+ scopeStatus["MockScope1"].movementStarted = 0;
66+ scopeStatus["MockScope1"].positionedAtBeginning = 0;
6767
68− lensStatus["MockLens2"].movementStarted = 0;
69− lensStatus["MockLens2"].positionedAtBeginning = 0;
68+ scopeStatus["MockScope2"].movementStarted = 0;
69+ scopeStatus["MockScope2"].positionedAtBeginning = 0;
7070
71− lensStatus["MockLens3"].movementStarted = 0;
72− lensStatus["MockLens3"].positionedAtBeginning = 0;
71+ scopeStatus["MockScope3"].movementStarted = 0;
72+ scopeStatus["MockScope3"].positionedAtBeginning = 0;
7373
74− lensStatus["MockLens4"].movementStarted = 0;
75− lensStatus["MockLens4"].positionedAtBeginning = 0;
74+ scopeStatus["MockScope4"].movementStarted = 0;
75+ scopeStatus["MockScope4"].positionedAtBeginning = 0;
7676
77− lensStatus["MockLens5"].movementStarted = 0;
78− lensStatus["MockLens5"].positionedAtBeginning = 0;
77+ scopeStatus["MockScope5"].movementStarted = 0;
78+ scopeStatus["MockScope5"].positionedAtBeginning = 0;
7979 }
8080
8181 SignalSpy {
82− id: lensLoadedSpy
82+ id: scopeLoadedSpy
8383 target: dashContent
84− signalName: "lensLoaded"
84+ signalName: "scopeLoaded"
8585 }
8686
8787 SignalSpy {
@@ -101,78 +101,81 @@ Item {
101101 when: windowShown
102102
103103 function init() {
104− lensLoadedSpy.clear();
104+ scopeLoadedSpy.clear();
105105 movementStartedSpy.clear();
106106 contentEndReachedSpy.clear()
107− clear_lens_status();
107+ clear_scope_status();
108108
109− // clear, wait for dahs to empty and load lenses.
109+ // clear, wait for dahs to empty and load scopes.
110110 var dashContentList = findChild(dashContent, "dashContentList");
111111 verify(dashContentList != undefined)
112− lensesModel.clear();
112+ scopesModel.clear();
113113 tryCompare(dashContentList, "count", 0);
114− lensesModel.load();
114+ scopesModel.load();
115115 }
116116
117117 function test_movement_started_signal() {
118− dashContent.setCurrentLensAtIndex(3, true, false);
118+ dashContent.setCurrentScopeAtIndex(3, true, false);
119119
120120 var dashContentList = findChild(dashContent, "dashContentList");
121121 verify(dashContentList != undefined)
122− tryCompare(lensLoadedSpy, "count", 5);
122+
123+ tryCompare(scopeLoadedSpy, "count", 5);
123124
124125 dashContentList.movementStarted();
126+
125127 compare(movementStartedSpy.count, 1, "DashContent should have emitted movementStarted signal when content list did.");
126− compare(lensStatus["MockLens1"].movementStarted, 1, "MockLens1 should have emitted movementStarted signal when content list did.");
127− compare(lensStatus["MockLens2"].movementStarted, 1, "MockLens2 should have emitted movementStarted signal when content list did.");
128− compare(lensStatus["MockLens3"].movementStarted, 1, "MockLens3 should have emitted movementStarted signal when content list did.");
129− compare(lensStatus["MockLens4"].movementStarted, 1, "MockLens4 should have emitted movementStarted signal when content list did.");
130− compare(lensStatus["MockLens5"].movementStarted, 1, "MockLens5 should have emitted movementStarted signal when content list did.");
128+ compare(scopeStatus["MockScope1"].movementStarted, 1, "MockScope1 should have emitted movementStarted signal when content list did.");
129+ compare(scopeStatus["MockScope2"].movementStarted, 1, "MockScope2 should have emitted movementStarted signal when content list did.");
130+ compare(scopeStatus["MockScope3"].movementStarted, 1, "MockScope3 should have emitted movementStarted signal when content list did.");
131+ compare(scopeStatus["MockScope4"].movementStarted, 1, "MockScope4 should have emitted movementStarted signal when content list did.");
132+ compare(scopeStatus["MockScope5"].movementStarted, 1, "MockScope5 should have emitted movementStarted signal when content list did.");
131133 }
132134
133135 function test_positioned_at_beginning_signal() {
134− dashContent.setCurrentLensAtIndex(3, true, false);
136+ dashContent.setCurrentScopeAtIndex(3, true, false);
135137
136− tryCompare(lensLoadedSpy, "count", 5);
138+ tryCompare(scopeLoadedSpy, "count", 5);
137139
138140 dashContent.positionedAtBeginning();
139− compare(lensStatus["MockLens1"].positionedAtBeginning, 1, "MockLens1 should have emitted positionedAtBeginning signal when DashContent did.");
140− compare(lensStatus["MockLens2"].positionedAtBeginning, 1, "MockLens2 should have emitted positionedAtBeginning signal when DashContent did.");
141− compare(lensStatus["MockLens3"].positionedAtBeginning, 1, "MockLens3 should have emitted positionedAtBeginning signal when DashContent did.");
142− compare(lensStatus["MockLens4"].positionedAtBeginning, 1, "MockLens4 should have emitted positionedAtBeginning signal when DashContent did.");
143− compare(lensStatus["MockLens5"].positionedAtBeginning, 1, "MockLens5 should have emitted positionedAtBeginning signal when DashContent did.");
141+ compare(scopeStatus["MockScope1"].positionedAtBeginning, 1, "MockScope1 should have emitted positionedAtBeginning signal when DashContent did.");
142+ compare(scopeStatus["MockScope2"].positionedAtBeginning, 1, "MockScope2 should have emitted positionedAtBeginning signal when DashContent did.");
143+ compare(scopeStatus["MockScope3"].positionedAtBeginning, 1, "MockScope3 should have emitted positionedAtBeginning signal when DashContent did.");
144+ compare(scopeStatus["MockScope4"].positionedAtBeginning, 1, "MockScope4 should have emitted positionedAtBeginning signal when DashContent did.");
145+ compare(scopeStatus["MockScope5"].positionedAtBeginning, 1, "MockScope5 should have emitted positionedAtBeginning signal when DashContent did.");
144146 }
145147
146− function test_lens_loaded() {
147− tryCompare(lensLoadedSpy, "count", 5);
148+ function test_scope_loaded() {
149+ tryCompare(scopeLoadedSpy, "count", 5);
148150 }
149151
150152 function test_content_end_reached() {
151153 var dashContentList = findChild(dashContent, "dashContentList");
152154 verify(dashContentList != undefined);
153− tryCompare(lensLoadedSpy, "count", 5);
154155
155− dashContent.setCurrentLensAtIndex(0, true, false);
156+ tryCompare(scopeLoadedSpy, "count", 5);
157+ dashContent.setCurrentScopeAtIndex(0, true, false);
156158 dashContentList.currentItem.item.endReached();
157159
158160 compare(contentEndReachedSpy.count, 1);
159161 }
160162
161− // This tests that setting the current lens index will end up at the correct index even if
162− // the lenses are loaded asynchrounsly.
163− function test_set_current_lens_index_async() {
164− verify(lensesModel.loaded == false);
163+ // This tests that setting the current scope index will end up at the correct index even if
164+ // the scopes are loaded asynchrounsly.
165+ function test_set_current_scope_index_async() {
166+ verify(scopesModel.loaded == false);
165167
166168 // next index is 1 if current is -1, otherwise it's current + 1
167169 var next_index = ((dashContent.currentIndex == -1 ? 0 : dashContent.currentIndex) + 1) % 5
168170
169− dashContent.setCurrentLensAtIndex(next_index, true, false);
171+ dashContent.setCurrentScopeAtIndex(next_index, true, false);
170172 tryCompare(dashContent, "currentIndex", next_index);
171− verify(lensesModel.loaded == true);
173+ verify(scopesModel.loaded == true);
172174
173− // test greater than lens count.
174− dashContent.setCurrentLensAtIndex(lensesModel.count, true, false);
175− compare(dashContent.currentIndex, 4);
175+ // test greater than scope count.
176+ var currentScopeIndex = dashContent.currentIndex;
177+ dashContent.setCurrentScopeAtIndex(scopesModel.count, true, false);
178+ compare(dashContent.currentIndex, currentScopeIndex, "Scope should not change if changing to greater index than count");
176179 }
177180
178181 function get_current_item_object_name() {
@@ -187,18 +190,18 @@ Item {
187190 return "";
188191 }
189192
190− function test_lens_mapping_data() {
193+ function test_scope_mapping_data() {
191194 return [
192− {tag: "index0", index: 0, objectName: "fake_lensView1"},
193− {tag: "index1", index: 1, objectName: "fake_lensView2"},
194− {tag: "index2", index: 2, objectName: "fake_lensView3"},
195− {tag: "index3", index: 3, objectName: "fake_lensView4"},
196− {tag: "index4", index: 4, objectName: "fake_generic_lensView"}
195+ {tag: "index0", index: 0, objectName: "fake_scopeView1"},
196+ {tag: "index1", index: 1, objectName: "fake_scopeView2"},
197+ {tag: "index2", index: 2, objectName: "fake_scopeView3"},
198+ {tag: "index3", index: 3, objectName: "fake_scopeView4"},
199+ {tag: "index4", index: 4, objectName: "fake_generic_scopeView"}
197200 ]
198201 }
199202
200− function test_lens_mapping(data) {
201− dashContent.setCurrentLensAtIndex(data.index, true, false);
203+ function test_scope_mapping(data) {
204+ dashContent.setCurrentScopeAtIndex(data.index, true, false);
202205 tryCompareFunction(get_current_item_object_name, data.objectName)
203206 }
204207
tests/qmltests/Dash/tst_FilterGrids.qml−1
@@ -108,7 +108,6 @@ Rectangle {
108108 function test_clicked_signal_data() {
109109 return [
110110 {tag: "VideosFilterGrid", component: "Video/VideosFilterGrid.qml"},
111− {tag: "PeopleFilterGrid", component: "People/PeopleFilterGrid.qml"},
112111 {tag: "MusicFilterGrid", component: "Music/MusicFilterGrid.qml"},
113112 {tag: "ApplicationsFilterGrid", component: "Apps/ApplicationsFilterGrid.qml"}
114113 ]
tests/qmltests/Dash/tst_GenericLensView.qml → tests/qmltests/Dash/tst_GenericScopeView.qmlrenamed+10−10
@@ -26,27 +26,27 @@ Item {
2626 width: units.gu(120)
2727 height: units.gu(80)
2828
29− Lenses {
30− id: lenses
29+ Scopes {
30+ id: scopes
3131 }
3232
33− GenericLensView {
34− id: genericLensView
33+ GenericScopeView {
34+ id: genericScopeView
3535 anchors.fill: parent
3636
3737 UT.UnityTestCase {
38− name: "GenericLensView"
39− when: lenses.loaded
38+ name: "GenericScopeView"
39+ when: scopes.loaded
4040
4141 function init() {
42− genericLensView.lens = lenses.get(0)
42+ genericScopeView.scope = scopes.get(0)
4343 }
4444
4545 function test_isCurrent() {
46− var pageHeader = findChild(genericLensView, "pageHeader");
47− genericLensView.isCurrent = true
46+ var pageHeader = findChild(genericScopeView, "pageHeader");
47+ genericScopeView.isCurrent = true
4848 pageHeader.searchQuery = "test"
49− genericLensView.isCurrent = false
49+ genericScopeView.isCurrent = false
5050 tryCompare(pageHeader, "searchQuery", "")
5151 }
5252 }
tests/qmltests/Dash/tst_PeoplePreview.qmldeleted−254
@@ -1,254 +0,0 @@
1−/*
2− * Copyright 2013 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import QtTest 1.0
19−import ".."
20−import "../../../Dash/People"
21−import Ubuntu.Components 0.1
22−import Unity.Test 0.1 as UT
23−
24−Item {
25− id: root
26− width: units.gu(140)
27− height: units.gu(100)
28−
29− property bool helper: false
30−
31− PeoplePreview {
32− id: preview
33− anchors.fill: parent
34− anchors.rightMargin: units.gu(20)
35− }
36−
37− Column {
38− anchors {
39− left: preview.right
40− top: parent.top
41− right: parent.right
42− bottom: parent.bottom
43− margins: units.gu(1)
44− }
45− spacing: units.gu(1)
46−
47− Button {
48− text: "Clear all"
49− anchors { left: parent.left; right: parent.right }
50− onClicked: mockModel.clear();
51− }
52− Repeater {
53− model: testCase.test_click_items_data()
54− Button {
55− text: testCase.test_click_items_data()[index].tag
56− anchors { left: parent.left; right: parent.right }
57− onClicked: testCase.fillModel(testCase.test_click_items_data()[index]);
58− }
59− }
60− }
61−
62− ListModel {
63− id: mockModel
64− }
65−
66− SignalSpy {
67− id: clickSpy
68− signalName: "clicked"
69− }
70−
71− UT.UnityTestCase {
72− id: testCase
73− name: "PeoplePreview"
74− when: windowShown
75−
76− function fillModel(data) {
77− mockModel.clear();
78− mockModel.append(data);
79− preview.model = mockModel.get(0);
80− wait(0);
81− }
82−
83− function test_click_items_data() {
84− return [
85− {
86− tag: "All Data",
87− displayName: "Round Robin",
88− avatar: "../../graphics/clock.png",
89− status: "very busy",
90− statusTime: "1/6/2013 16:19:01",
91− statusServiceIcon: "../../../graphics/clock.png",
92− phoneNumbers: [{number:"123456", type: "voice", location: "Mars"}, {number: "654321"}],
93− emailAddresses: [{address:"robin@ntp.org"}, {address: "sirspamalot@foo.com"}],
94− imAccounts: [{address:"rr@jabber.org", protocol: "xmpp"}, {address: "sirspamalot@foo.com", protocol: "secret service messenger"}],
95− addresses: [
96− {street: "Middle of nowhere", poBox: 1, extension: "none", locality: "Mars", region: "all of it", postalCode: "٣٤٥٦", country: "There is only one on mars", addressFormat: "unreadable for you"},
97− {street: "Blue fin building"}
98− ]
99− },
100− {
101− tag: "Only Status",
102− status: "very busy",
103− statusTime: "1/6/2013 16:19:01",
104− statusServiceIcon: "../../../graphics/clock.png",
105− },
106− {
107− tag: "One Number",
108− phoneNumbers: [{number:"123456", type: "voice", location: "Mars"}],
109− },
110− {
111− tag: "Three Numbers",
112− phoneNumbers: [{number:"123456", type: "voice", location: "Mars"}, {number: "654321"}, {number: "666", type: "voice", location: "h3ll"}],
113− },
114− {
115− tag: "Only Mails",
116− emailAddresses: [{address:"robin@ntp.org"}, {address: "sirspamalot@foo.com"}],
117− },
118− {
119− tag: "Only IM",
120− imAccounts: [{address:"rr@jabber.org", protocol: "xmpp"}, {address: "sirspamalot@foo.com", protocol: "secret service messenger"}],
121− },
122− {
123− tag: "Only Address",
124− addresses: [
125− {street: "Middle of nowhere", poBox: 1, extension: "none", locality: "Mars", region: "all of it", postalCode: "٣٤٥٦", country: "There is only one on mars", addressFormat: "unreadable for you"},
126− ]
127− },
128− {
129− tag: "Std Contact",
130− displayName: "Round Robin",
131− avatar: "../../graphics/clock.png",
132− phoneNumbers: [{number:"123456", type: "voice", location: "Mars"}],
133− emailAddresses: [{address:"robin@ntp.org"}],
134− addresses: [
135− {street: "Middle of nowhere", poBox: 1, extension: "none", locality: "Mars", region: "all of it", postalCode: "٣٤٥٦", country: "There is only one on mars", addressFormat: "unreadable for you"},
136− {street: "Blue fin building"}
137− ]
138− },
139− {
140− tag: "Std + Status",
141− displayName: "Round Robin",
142− avatar: "../../graphics/clock.png",
143− status: "very busy",
144− statusTime: "1/6/2013 16:19:01",
145− statusServiceIcon: "../../../graphics/clock.png",
146− phoneNumbers: [{number:"123456", type: "voice", location: "Mars"}],
147− emailAddresses: [{address:"robin@ntp.org"}],
148− addresses: [
149− {street: "Middle of nowhere", poBox: 1, extension: "none", locality: "Mars", region: "all of it", postalCode: "٣٤٥٦", country: "There is only one on mars", addressFormat: "unreadable for you"},
150− {street: "Blue fin building"}
151− ]
152− },
153− ]
154− }
155−
156− function test_click_items(data) {
157− fillModel(data)
158−
159− // Check if status field is visible
160− var field = findChild(preview, "statusField");
161− if (data.status != undefined) {
162− compare(field.visible, true, "status field is not visible");
163− verifyClick(field);
164− } else {
165− compare(field.visible, false, "status field is visible while it should not");
166− }
167−
168− // Check if there are phoneNumber.count phone fields
169− var i = 0;
170− if (data.phoneNumbers != undefined) {
171− for (; i < data.phoneNumbers.length; ++i) {
172− var field = findChild(preview, "phoneField" + i);
173− verify(field != undefined);
174− verifyPhoneNumberClick(field);
175− }
176− i++;
177− }
178− // Check if there are no more phone fields
179− var field = findChild(preview, "phoneField" + i);
180− compare(field, undefined, "There is a phone number field too much!");
181−
182−
183− // Check if email adresses are here
184− var i = 0;
185− if (data.emailAddresses != undefined) {
186− for (; i < data.emailAddresses.length; ++i) {
187− var field = findChild(preview, "emailField" + i);
188− verify(field != undefined);
189− verifyClick(field);
190− }
191− i++;
192− }
193− // Check if there are no more email fields
194− var field = findChild(preview, "emailField" + i);
195− compare(field, undefined, "There is a email field too much!");
196−
197−
198− // Check if IM accounts are here
199− var i = 0;
200− if (data.imAccounts != undefined) {
201− for (; i < data.imAccounts.length; ++i) {
202− var field = findChild(preview, "imField" + i);
203− verify(field != undefined);
204− verifyClick(field);
205− }
206− i++;
207− }
208− // Check if there are no more IM fields
209− var field = findChild(preview, "imField" + i);
210− compare(field, undefined, "There is a IM field too much!");
211−
212− // Check if email adresses are here
213− var i = 0;
214− if (data.addresses != undefined) {
215− for (; i < data.addresses.length; ++i) {
216− var field = findChild(preview, "addressField" + i);
217− verify(field != undefined);
218− verifyClick(field);
219− }
220− i++;
221− }
222− // Check if there are no more fields fields
223− var field = findChild(preview, "addressField" + i);
224− compare(field, undefined, "There is an address field too much!");
225− }
226−
227− function verifyClick(field) {
228− waitForRendering(field)
229− clickSpy.signalName = "" // Get rid of a warning if new target doesn't support previous signal name
230− clickSpy.target = field;
231− clickSpy.clear();
232− clickSpy.signalName = "clicked";
233− compare(clickSpy.count, 0, "Could not reset signal spy");
234− mouseClick(field, field.width / 2, field.height / 2);
235− compare(clickSpy.count, 1, "Could not click on field " + field);
236− }
237−
238− function verifyPhoneNumberClick(field) {
239− waitForRendering(field)
240− clickSpy.target = field;
241− clickSpy.clear();
242− clickSpy.signalName = "phoneClicked";
243− compare(clickSpy.count, 0, "Could not reset signal spy");
244− mouseClick(field, 1 , field.height / 2);
245− compare(clickSpy.count, 1, "Could not click on phone field");
246−
247− clickSpy.clear();
248− clickSpy.signalName = "textClicked";
249− compare(clickSpy.count, 0, "Could not reset signal spy");
250− mouseClick(field, field.width - 1 , field.height / 2);
251− compare(clickSpy.count, 1, "Could not click on Message field");
252− }
253− }
254−}
tests/qmltests/Dash/tst_LensView.qml → tests/qmltests/Dash/tst_ScopeView.qmlrenamed+12−12
@@ -25,27 +25,27 @@ Item {
2525 width: units.gu(120)
2626 height: units.gu(80)
2727
28− Lenses {
29− id: lenses
28+ Scopes {
29+ id: scopes
3030 }
3131
32− LensView {
33− id: lensView
32+ ScopeView {
33+ id: scopeView
3434 anchors.fill: parent
3535
3636 TestCase {
37− name: "LensView"
38− when: lenses.loaded
37+ name: "ScopeView"
38+ when: scopes.loaded
3939
4040 function init() {
41− lensView.lens = lenses.get(0)
41+ scopeView.scope = scopes.get(0)
4242 }
4343
44− function test_changeLens() {
45− lensView.lens.searchQuery = "test"
46− lensView.lens = lenses.get(1)
47− lensView.lens = lenses.get(0)
48− tryCompare(lensView.lens, "searchQuery", "")
44+ function test_changeScope() {
45+ scopeView.scope.searchQuery = "test"
46+ scopeView.scope = scopes.get(1)
47+ scopeView.scope = scopes.get(0)
48+ tryCompare(scopeView.scope, "searchQuery", "")
4949 }
5050 }
5151 }
tests/qmltests/plugins/Unity/CMakeLists.txt+2−2
@@ -22,8 +22,8 @@ set(UnityQML_SOURCES
2222 ${CMAKE_SOURCE_DIR}/plugins/Unity/categories.cpp
2323 ${CMAKE_SOURCE_DIR}/plugins/Unity/categoryfilter.cpp
2424 ${CMAKE_SOURCE_DIR}/plugins/Utils/qsortfilterproxymodelqml.cpp
25− fake_lens.cpp
26− fake_lenses.cpp
25+ fake_scope.cpp
26+ fake_scopes.cpp
2727 fake_unity_plugin.cpp
2828 fake_launchermodel.cpp
2929)
tests/qmltests/plugins/Unity/fake_lens.cpp → tests/qmltests/plugins/Unity/fake_scope.cpprenamed+15−13
@@ -15,7 +15,7 @@
1515 */
1616
1717// Self
18−#include "fake_lens.h"
18+#include "fake_scope.h"
1919
2020#include <dee.h>
2121#include "paths.h"
@@ -25,7 +25,7 @@ static DeeModel* create_results_model(unsigned category_count, unsigned result_c
2525
2626// TODO: Implement remaining pieces
2727
28−Lens::Lens(QObject* parent)
28+Scope::Scope(QObject* parent)
2929: QObject(parent),
3030 m_visible(false),
3131 m_categories(new Categories(this)),
@@ -35,10 +35,9 @@ Lens::Lens(QObject* parent)
3535 m_results->setModel(create_results_model(4, 30));
3636
3737 m_categories->setResultModel(m_results);
38− m_categories->setGlobalResultModel(m_results);
3938}
4039
41−Lens::Lens(QString const& id,
40+Scope::Scope(QString const& id,
4241 QString const& name,
4342 bool visible,
4443 QObject* parent)
@@ -53,44 +52,44 @@ Lens::Lens(QString const& id,
5352 m_results->setModel(create_results_model(4, 30));
5453
5554 m_categories->setResultModel(m_results);
56− m_categories->setGlobalResultModel(m_results);
5755}
5856
59−QString Lens::id() const {
57+QString Scope::id() const {
6058 return m_id;
6159}
6260
63−QString Lens::name() const {
61+QString Scope::name() const {
6462 return m_name;
6563}
6664
67−QString Lens::searchQuery() const {
65+QString Scope::searchQuery() const {
6866 return m_searchQuery;
6967}
7068
71−void Lens::setName(const QString &str) {
69+void Scope::setName(const QString &str) {
7270 if (str != m_name) {
7371 m_name = str;
7472 Q_EMIT nameChanged(m_name);
7573 }
7674}
7775
78−void Lens::setSearchQuery(const QString &str) {
76+void Scope::setSearchQuery(const QString &str) {
7977 if (str != m_searchQuery) {
8078 m_searchQuery = str;
8179 Q_EMIT searchQueryChanged(m_searchQuery);
8280 }
8381}
8482
85−bool Lens::visible() const {
83+bool Scope::visible() const {
8684 return m_visible;
8785}
8886
89−Categories* Lens::categories() const {
87+Categories* Scope::categories() const {
9088 return m_categories;
9189}
9290
9391static const gchar * categories_model_schema[] = {
92+ "s", //ID
9493 "s", // DISPLAY_NAME
9594 "s", // ICON_HINT
9695 "s", // RENDERER_NAME
@@ -109,6 +108,7 @@ DeeModel* create_categories_model(unsigned category_count) {
109108 for(unsigned i = 0; i < category_count; ++i)
110109 {
111110 dee_model_append(category_model,
111+ std::to_string(i).c_str(),
112112 ("Category "+std::to_string(i)).c_str(),
113113 "gtk-apply",
114114 "grid",
@@ -125,6 +125,7 @@ static const gchar * results_model_schema[] = {
125125 "s", // URI
126126 "s", // ICON_HINT
127127 "u", // CATEGORY
128+ "u", // RESULT_TYPE
128129 "s", // MIMETYPE
129130 "s", // TITLE
130131 "s", // COMMENT
@@ -154,8 +155,9 @@ DeeModel* create_results_model(unsigned category_count, unsigned result_count) {
154155
155156 dee_model_append(results_model,
156157 ("uri://result."+std::to_string(i)).c_str(),
157− (shellAppDirectory() + "Dash/graphics/lensIcons/" + (icons[i%G_N_ELEMENTS(icons)])).toLatin1().data(),
158+ (shellAppDirectory() + "Dash/graphics/scopeIcons/" + (icons[i%G_N_ELEMENTS(icons)])).toLatin1().data(),
158159 category,
160+ 0,
159161 "application/x-desktop",
160162 ("Title."+std::to_string(i)).c_str(),
161163 ("Comment."+std::to_string(i)).c_str(),
tests/qmltests/plugins/Unity/fake_lens.h → tests/qmltests/plugins/Unity/fake_scope.hrenamed+6−6
@@ -14,14 +14,14 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−#ifndef FAKE_LENS_H
18−#define FAKE_LENS_H
17+#ifndef FAKE_SCOPE_H
18+#define FAKE_SCOPE_H
1919
2020// Qt
2121#include <QObject>
2222#include "categories.h"
2323
24−class Lens : public QObject
24+class Scope : public QObject
2525{
2626 Q_OBJECT
2727 Q_PROPERTY(QString id READ id NOTIFY idChanged)
@@ -31,8 +31,8 @@ class Lens : public QObject
3131 Q_PROPERTY(Categories* categories READ categories NOTIFY categoriesChanged)
3232
3333public:
34− Lens(QObject* parent = 0);
35− Lens(QString const& id, QString const& name, bool visible, QObject* parent = 0);
34+ Scope(QObject* parent = 0);
35+ Scope(QString const& id, QString const& name, bool visible, QObject* parent = 0);
3636
3737 QString id() const;
3838 QString name() const;
@@ -60,4 +60,4 @@ private:
6060 DeeListModel* m_results;
6161};
6262
63−#endif // FAKE_LENS_H
63+#endif // FAKE_SCOPE_H
tests/qmltests/plugins/Unity/fake_lenses.cpp → tests/qmltests/plugins/Unity/fake_scopes.cpprenamed+38−38
@@ -17,21 +17,21 @@
1717 */
1818
1919// Self
20−#include "fake_lenses.h"
20+#include "fake_scopes.h"
2121
2222// TODO: Implement remaining pieces, like Categories (i.e. LensView now gives warnings)
2323
2424// Qt
2525#include <QTimer>
2626
27−Lenses::Lenses(QObject *parent)
27+Scopes::Scopes(QObject *parent)
2828: QAbstractListModel(parent)
2929, m_loaded(false)
3030, timer(this)
3131{
32− m_roles[Lenses::RoleLens] = "lens";
33− m_roles[Lenses::RoleId] = "id";
34− m_roles[Lenses::RoleVisible] = "visible";
32+ m_roles[Scopes::RoleScope] = "scope";
33+ m_roles[Scopes::RoleId] = "id";
34+ m_roles[Scopes::RoleVisible] = "visible";
3535
3636 QObject::connect(this, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SIGNAL(countChanged()));
3737 QObject::connect(this, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SIGNAL(countChanged()));
@@ -39,22 +39,22 @@ Lenses::Lenses(QObject *parent)
3939
4040 timer.setSingleShot(true);
4141 timer.setInterval(100);
42− QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(updateLenses()));
42+ QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(updateScopes()));
4343 load();
4444}
4545
46−Lenses::~Lenses()
46+Scopes::~Scopes()
4747{
4848}
4949
50−void Lenses::updateLenses()
50+void Scopes::updateScopes()
5151{
5252 clear();
53− addLens(new Lens("MockLens1", "People", true, this));
54− addLens(new Lens("MockLens2", "Music", false, this));
55− addLens(new Lens("MockLens3", "Home", true, this));
56− addLens(new Lens("MockLens4", "Applications", true, this));
57− addLens(new Lens("MockLens5", "Videos", true, this));
53+ addScope(new Scope("MockScope1", "People", true, this));
54+ addScope(new Scope("MockScope2", "Music", false, this));
55+ addScope(new Scope("MockScope3", "Home", true, this));
56+ addScope(new Scope("MockScope4", "Applications", true, this));
57+ addScope(new Scope("MockScope5", "Videos", true, this));
5858
5959 if (!m_loaded) {
6060 m_loaded = true;
@@ -62,13 +62,13 @@ void Lenses::updateLenses()
6262 }
6363}
6464
65−void Lenses::clear()
65+void Scopes::clear()
6666{
6767 timer.stop();
68− if (m_lenses.size() > 0) {
69− beginRemoveRows(QModelIndex(), 0, m_lenses.count()-1);
70− qDeleteAll(m_lenses);
71− m_lenses.clear();
68+ if (m_scopes.size() > 0) {
69+ beginRemoveRows(QModelIndex(), 0, m_scopes.count()-1);
70+ qDeleteAll(m_scopes);
71+ m_scopes.clear();
7272 endRemoveRows();
7373 }
7474
@@ -78,69 +78,69 @@ void Lenses::clear()
7878 }
7979}
8080
81−void Lenses::load()
81+void Scopes::load()
8282{
8383 timer.start();
8484}
8585
86−QHash<int, QByteArray> Lenses::roleNames() const
86+QHash<int, QByteArray> Scopes::roleNames() const
8787{
8888 return m_roles;
8989}
9090
91−int Lenses::rowCount(const QModelIndex&) const
91+int Scopes::rowCount(const QModelIndex&) const
9292{
93− return m_lenses.count();
93+ return m_scopes.count();
9494}
9595
96−QVariant Lenses::data(const QModelIndex& index, int role) const
96+QVariant Scopes::data(const QModelIndex& index, int role) const
9797{
98− if (!index.isValid() || index.row() >= m_lenses.size()) {
98+ if (!index.isValid() || index.row() >= m_scopes.size()) {
9999 return QVariant();
100100 }
101101
102− Lens* lens = m_lenses.at(index.row());
102+ Scope* scope = m_scopes.at(index.row());
103103
104− if (role == Lenses::RoleLens) {
105− return QVariant::fromValue(lens);
106− } else if (role == Lenses::RoleId) {
107− return QVariant::fromValue(lens->id());
108− } else if (role == Lenses::RoleVisible) {
109− return QVariant::fromValue(lens->visible());
104+ if (role == Scopes::RoleScope) {
105+ return QVariant::fromValue(scope);
106+ } else if (role == Scopes::RoleId) {
107+ return QVariant::fromValue(scope->id());
108+ } else if (role == Scopes::RoleVisible) {
109+ return QVariant::fromValue(scope->visible());
110110 } else {
111111 return QVariant();
112112 }
113113}
114114
115−QVariant Lenses::get(int row) const
115+QVariant Scopes::get(int row) const
116116{
117117 return data(QAbstractListModel::index(row), 0);
118118}
119119
120−QVariant Lenses::get(QString const&) const
120+QVariant Scopes::get(QString const&) const
121121{
122122 return QVariant();
123123}
124124
125−QModelIndex Lenses::parent(const QModelIndex&) const
125+QModelIndex Scopes::parent(const QModelIndex&) const
126126{
127127 return QModelIndex();
128128}
129129
130−bool Lenses::loaded() const
130+bool Scopes::loaded() const
131131{
132132 return m_loaded;
133133}
134134
135−int Lenses::count() const
135+int Scopes::count() const
136136{
137137 return rowCount();
138138}
139139
140−void Lenses::addLens(Lens* lens)
140+void Scopes::addScope(Scope* scope)
141141{
142142 int index = rowCount();
143143 beginInsertRows(QModelIndex(), index, index);
144− m_lenses.append(lens);
144+ m_scopes.append(scope);
145145 endInsertRows();
146146}
tests/qmltests/plugins/Unity/fake_lenses.h → tests/qmltests/plugins/Unity/fake_scopes.hrenamed+13−13
@@ -16,18 +16,18 @@
1616 * Author: Nick Dedekind <nick.dedekind@canonical.com>
1717 */
1818
19−#ifndef FAKE_LENSES_H
20−#define FAKE_LENSES_H
19+#ifndef FAKE_SCOPES_H
20+#define FAKE_SCOPES_H
2121
2222// Local
23−#include "fake_lens.h"
23+#include "fake_scope.h"
2424
2525// Qt
2626#include <QAbstractListModel>
2727#include <QList>
2828#include <QTimer>
2929
30−class Lenses : public QAbstractListModel
30+class Scopes : public QAbstractListModel
3131{
3232 Q_OBJECT
3333 Q_ENUMS(Roles)
@@ -35,11 +35,11 @@ class Lenses : public QAbstractListModel
3535 Q_PROPERTY(int count READ count NOTIFY countChanged)
3636
3737public:
38− explicit Lenses(QObject *parent = 0);
39− ~Lenses();
38+ explicit Scopes(QObject *parent = 0);
39+ ~Scopes();
4040
4141 enum Roles {
42− RoleLens,
42+ RoleScope,
4343 RoleId,
4444 RoleVisible
4545 };
@@ -47,9 +47,9 @@ public:
4747 Q_INVOKABLE int rowCount(const QModelIndex& parent = QModelIndex()) const;
4848
4949 Q_INVOKABLE QVariant get(int row) const;
50− Q_INVOKABLE QVariant get(const QString& lens_id) const;
50+ Q_INVOKABLE QVariant get(const QString& scope_id) const;
5151
52− Q_INVOKABLE void addLens(Lens* lens);
52+ Q_INVOKABLE void addScope(Scope* scope);
5353
5454 Q_INVOKABLE void clear();
5555 Q_INVOKABLE void load();
@@ -62,18 +62,18 @@ public:
6262 int count() const;
6363
6464Q_SIGNALS:
65− void activateLensRequested(const QString& lens_id);
65+ void activateScopeRequested(const QString& scope_id);
6666 void loadedChanged(bool);
6767 void countChanged();
6868
6969private Q_SLOTS:
70− void updateLenses();
70+ void updateScopes();
7171
7272private:
73− QList<Lens*> m_lenses;
73+ QList<Scope*> m_scopes;
7474 QHash<int, QByteArray> m_roles;
7575 bool m_loaded;
7676 QTimer timer;
7777};
7878
79−#endif // LENSES_H
79+#endif // SCOPES_H
tests/qmltests/plugins/Unity/fake_unity_plugin.cpp+3−3
@@ -20,7 +20,7 @@
2020#include "fake_unity_plugin.h"
2121
2222// local
23−#include "fake_lenses.h"
23+#include "fake_scopes.h"
2424#include "categories.h"
2525#include "categoryfilter.h"
2626#include "fake_launchermodel.h"
@@ -37,8 +37,8 @@ void FakeUnityPlugin::registerTypes(const char *uri)
3737
3838 Q_ASSERT(uri == QLatin1String("Unity"));
3939
40− qmlRegisterType<Lenses>(uri, 0, 1, "Lenses");
41− qmlRegisterType<Lens>(uri, 0, 1, "Lens");
40+ qmlRegisterType<Scopes>(uri, 0, 1, "Scopes");
41+ qmlRegisterType<Scope>(uri, 0, 1, "Scope");
4242 qmlRegisterType<Categories>(uri, 0, 1, "Categories");
4343 qmlRegisterType<CategoryFilter>(uri, 0, 1, "CategoryFilter");
4444 qmlRegisterType<LauncherModel>(uri, 0, 1, "LauncherModel");