on xenial help sign in
merged with trunk
031898fNick Dedekind
CMakeLists.txt+3−4
@@ -91,10 +91,8 @@ enable_testing()
91
91
92# Autopilot tests
92# Autopilot tests
93include(autopilot)
93include(autopilot)
94−declare_autopilot_test(unity8 ${CMAKE_SOURCE_DIR}/tests/autopilot/)
94+declare_autopilot_test(shell unity8.shell ${CMAKE_SOURCE_DIR}/tests/autopilot/)
95−declare_autopilot_test(indicators_client ${CMAKE_SOURCE_DIR}/tests/autopilot/)
95+declare_autopilot_test(indicators_client unity8.indicators_client ${CMAKE_SOURCE_DIR}/tests/autopilot/)
96−
97−add_subdirectory(tests)
98
96
99set(SHELL_APP unity8)
97set(SHELL_APP unity8)
100
98
@@ -133,6 +131,7 @@ install(FILES ${QML_JS_FILES}
133 )
131 )
134
132
135# add subdirectories to build
133# add subdirectories to build
134+add_subdirectory(tests)
136add_subdirectory(plugins)
135add_subdirectory(plugins)
137add_subdirectory(src)
136add_subdirectory(src)
138
137
CODING+5−6
@@ -23,15 +23,12 @@ $ cd ~/unity8/trunk
23$ ./build --setup
23$ ./build --setup
24
24
25 this will:
25 this will:
26− - add the following PPA's
27− - ppa:phablet-team/desktop-deps
28− - ppa:canonical-qt5-edgers/qt5-proper
29− - ppa:ubuntu-sdk-team
26+ - add ppa:ubuntu-unity/next
30 - install the required dependencies to build, as well as run on the desktop
27 - install the required dependencies to build, as well as run on the desktop
31 - it should also install unity-scope-home and unity-lens-application which
28 - it should also install unity-scope-home and unity-lens-application which
32 are technically "recommends", not strict dependencies
29 are technically "recommends", not strict dependencies
33
30
34−Note, once the PPA's are added, the script runs apt-get update, if you have
31+Note, once the PPA is added, the script runs apt-get update, if you have
35any failures associated with it, the build script will bail out of the setup
32any failures associated with it, the build script will bail out of the setup
36and fail to install all the required dependencies.
33and fail to install all the required dependencies.
37
34
@@ -45,6 +42,7 @@ $ ./build
45You may also rebuild with the -c for clean, which just deletes the build
42You may also rebuild with the -c for clean, which just deletes the build
46directory.
43directory.
47
44
45+
48Running Unity 8 on your desktop
46Running Unity 8 on your desktop
49===============================
47===============================
50
48
@@ -73,6 +71,7 @@ Notes
73 - Create an EDS address book
71 - Create an EDS address book
74 - Populate the address book with sample data
72 - Populate the address book with sample data
75
73
74+
76Running Unity 8 on devices
75Running Unity 8 on devices
77==========================
76==========================
78- Ubuntu Touch builds are currently only available in 13.10 flavour
77- Ubuntu Touch builds are currently only available in 13.10 flavour
@@ -91,7 +90,6 @@ $ cd ~/unity/trunk
91$ ./run_on_device --setup
90$ ./run_on_device --setup
92 this will:
91 this will:
93 - install your public SSH key on the device
92 - install your public SSH key on the device
94− - add ppa:canonical-qt5-edgers/qt5-proper and ppa:phablet-team
95 - install the needed dependencies
93 - install the needed dependencies
96
94
97$ ./run_on_device
95$ ./run_on_device
@@ -109,6 +107,7 @@ $ ./run_on_device -p OR -k
109Notes
107Notes
110-----
108-----
111- using adb over TCP has some advantages, Google will be of help here
109- using adb over TCP has some advantages, Google will be of help here
110+ - NOTE: this is not yet available for flipped images
112 - TL;DR: `adb tcpip 5555; adb connect $your_device_ip`
111 - TL;DR: `adb tcpip 5555; adb connect $your_device_ip`
113 - you can persist the above via `adb shell setprop persist.adb.tcp.port 5555`
112 - you can persist the above via `adb shell setprop persist.adb.tcp.port 5555`
114 - it's unsafe - anyone can connect to your device
113 - it's unsafe - anyone can connect to your device
Components/OpenEffect.qml+9−1
@@ -19,11 +19,13 @@ import QtQuick 2.0
19Item {
19Item {
20 id: effect
20 id: effect
21 property bool enabled: topGapPx != positionPx || bottomGapPx != positionPx
21 property bool enabled: topGapPx != positionPx || bottomGapPx != positionPx
22+ property alias live: effectSource.live
22 property Item sourceItem
23 property Item sourceItem
23 property ShaderEffectSource source: ShaderEffectSource {
24 property ShaderEffectSource source: ShaderEffectSource {
25+ id: effectSource
24 sourceItem: effect.enabled ? effect.sourceItem : null
26 sourceItem: effect.enabled ? effect.sourceItem : null
25 hideSource: effect.enabled
27 hideSource: effect.enabled
26− live: effect.enabled
28+ live: false
27 sourceRect: {
29 sourceRect: {
28 if (effect.enabled) {
30 if (effect.enabled) {
29 Qt.rect(0, -effect.topOverflow, sourceItem.width, sourceItem.height + effect.topOverflow + effect.bottomOverflow)
31 Qt.rect(0, -effect.topOverflow, sourceItem.width, sourceItem.height + effect.topOverflow + effect.bottomOverflow)
@@ -33,6 +35,8 @@ Item {
33 }
35 }
34 }
36 }
35
37
38+ onEnabledChanged: if (!live && enabled) scheduleUpdate()
39+
36 /*!
40 /*!
37 \qmlproperty real positionPx
41 \qmlproperty real positionPx
38 The y coordinate of where to perform the split.
42 The y coordinate of where to perform the split.
@@ -60,6 +64,10 @@ Item {
60
64
61 property real __roundedPositionPx: Math.round(positionPx)
65 property real __roundedPositionPx: Math.round(positionPx)
62
66
67+ function scheduleUpdate() {
68+ source.scheduleUpdate();
69+ }
70+
63 ShaderEffect {
71 ShaderEffect {
64 id: top
72 id: top
65 visible: effect.enabled
73 visible: effect.enabled
Components/Showable.qml+5−14
@@ -52,7 +52,7 @@ Item {
52 function show() {
52 function show() {
53 required = true;
53 required = true;
54 if (created) {
54 if (created) {
55− __reallyShow(true);
55+ __reallyShow();
56 } else {
56 } else {
57 __shouldShow = true;
57 __shouldShow = true;
58 }
58 }
@@ -60,16 +60,12 @@ Item {
60
60
61 onCreatedChanged: {
61 onCreatedChanged: {
62 if (created && __shouldShow) {
62 if (created && __shouldShow) {
63− __reallyShow(true);
63+ __reallyShow();
64 __shouldShow = false;
64 __shouldShow = false;
65 }
65 }
66 }
66 }
67
67
68− function showWithoutAnimation() {
69− __reallyShow(false);
68+ function __reallyShow() {
70− }
71−
72− function __reallyShow(animated) {
73 if (!available) {
69 if (!available) {
74 return false;
70 return false;
75 }
71 }
@@ -81,13 +77,8 @@ Item {
81 }
77 }
82
78
83 if (showAnimation != undefined) {
79 if (showAnimation != undefined) {
84− if (animated) {
85− if (!showAnimation.running) {
80+ if (!showAnimation.running) {
86− showAnimation.restart()
81+ showAnimation.restart()
87− }
88− } else {
89− showAnimation.start();
90− showAnimation.complete();
91 }
82 }
92 } else {
83 } else {
93 visible = true;
84 visible = true;
Dash/Apps/ApplicationsFilterGrid.qml+3−3
@@ -36,7 +36,7 @@ FilterGrid {
36 objectName: "delegate" + index
36 objectName: "delegate" + index
37 Application {
37 Application {
38 id: application
38 id: application
39− desktopFile: model.column_7 ? stripProtocol(model.column_7) : model.desktopFile // FIXME: this is temporary
39+ desktopFile: model.dndUri ? stripProtocol(model.dndUri) : model.desktopFile // FIXME: this is temporary
40
40
41 function stripProtocol(uri) {
41 function stripProtocol(uri) {
42 var chunks = uri.split('file://')
42 var chunks = uri.split('file://')
@@ -44,11 +44,11 @@ FilterGrid {
44 }
44 }
45 }
45 }
46
46
47− property string icon: model.column_1 ? model.column_1 : "../../graphics/applicationIcons/" + application.icon + ".png" // FIXME: this is temporary
47+ property string icon: model.icon ? model.icon : "../../graphics/applicationIcons/" + application.icon + ".png" // FIXME: this is temporary
48
48
49 width: filterGrid.cellWidth
49 width: filterGrid.cellWidth
50 height: filterGrid.cellHeight
50 height: filterGrid.cellHeight
51− text: model.column_5 ? model.column_5 : application.name // FIXME: this is temporary
51+ text: model.title ? model.title : application.name // FIXME: this is temporary
52 imageWidth: units.gu(8)
52 imageWidth: units.gu(8)
53 imageHeight: units.gu(7.5)
53 imageHeight: units.gu(7.5)
54 source: IconUtil.from_gicon(icon)
54 source: IconUtil.from_gicon(icon)
Dash/DashApps.qml+10−8
@@ -81,17 +81,19 @@ ScopeView {
81 AppsAvailableForDownloadModel { id: appsAvailableForDownloadModel }
81 AppsAvailableForDownloadModel { id: appsAvailableForDownloadModel }
82
82
83 // FIXME this should not be needed, the backend should handle all that itself
83 // FIXME this should not be needed, the backend should handle all that itself
84− SortFilterProxyModel {
84+ property var installedModel: null
85− id: installedFilter
85+
86− dynamicSortFilter: true
86+ Repeater {
87− filterRole: 2 // this is the category id for each result
87+ model: scopeView.scope.categories
88− filterRegExp: /^3$/ // only proxy items that are category 3 - Installed
88+
89− model: dashContent.scopes.get("applications.scope").results
89+ delegate: Item {
90+ Component.onCompleted: if (index == 3) scopeView.installedModel = Qt.binding(function() { return model.results; });
91+ }
90 }
92 }
91
93
92 property var categoryModels: {
94 property var categoryModels: {
93 "FrequentlyUsedAppsModel": frequentlyUsedAppsModel,
95 "FrequentlyUsedAppsModel": frequentlyUsedAppsModel,
94− "InstalledApplicationsModel": installedFilter,
96+ "InstalledApplicationsModel": installedModel,
95 "AppsAvailableForDownloadModel": appsAvailableForDownloadModel,
97 "AppsAvailableForDownloadModel": appsAvailableForDownloadModel,
96 }
98 }
97
99
@@ -134,7 +136,7 @@ ScopeView {
134 shell.activateApplication(data);
136 shell.activateApplication(data);
135 }
137 }
136
138
137− item.model = categoryModels[modelName]
139+ item.model = Qt.binding(function() { return categoryModels[modelName]; });
138 item.clicked.connect(activateApplication);
140 item.clicked.connect(activateApplication);
139
141
140 }
142 }
Dash/DashHome.qml+20−31
@@ -52,42 +52,33 @@ ScopeView {
52 FrequentlyUsedAppsModel { id: appsModel }
52 FrequentlyUsedAppsModel { id: appsModel }
53
53
54 // FIXME this should be handled by the backends by populating the global search model
54 // FIXME this should be handled by the backends by populating the global search model
55− SortFilterProxyModel {
55+ property var musicModel: null
56− id: favouritesFilter
56+ property var videosModel: null
57− dynamicSortFilter: true
58− filterRole: 2
59− filterRegExp: /^0$/
60− }
61
57
62− SortFilterProxyModel {
58+ Repeater {
63− id: recentFilter
59+ id: musicRepeater
64− dynamicSortFilter: true
65− filterRole: 2
66− filterRegExp: /^2$/
67− }
68
60
69− SortFilterProxyModel {
61+ delegate: Item {
70− id: musicFilter
62+ Component.onCompleted: if (index == 1) musicModel = Qt.binding(function() { return model.results; });
71− dynamicSortFilter: true
63+ }
72− filterRole: 2
73− filterRegExp: /^1$/
74 }
64 }
75
65
76− SortFilterProxyModel {
66+ Repeater {
77− id: videosFilter
67+ id: videosRepeater
78− dynamicSortFilter: true
68+
79− filterRole: 2
69+ delegate: Item {
80− filterRegExp: /^3$/
70+ Component.onCompleted: if (index == 3) videosModel = Qt.binding(function() { return model.results; });
71+ }
81 }
72 }
82
73
83 Component.onCompleted: {
74 Component.onCompleted: {
84 var scope = dashContent.scopes.get("mockmusicmaster.scope")
75 var scope = dashContent.scopes.get("mockmusicmaster.scope")
85 if (scope) {
76 if (scope) {
86− musicFilter.model = dashContent.scopes.get("mockmusicmaster.scope").results
77+ musicRepeater.model = dashContent.scopes.get("mockmusicmaster.scope").categories
87 }
78 }
88 scope = dashContent.scopes.get("mockvideosmaster.scope")
79 scope = dashContent.scopes.get("mockvideosmaster.scope")
89 if (scope) {
80 if (scope) {
90− videosFilter.model = dashContent.scopes.get("mockvideosmaster.scope").results
81+ videosRepeater.model = dashContent.scopes.get("mockvideosmaster.scope").categories
91 }
82 }
92 }
83 }
93
84
@@ -95,19 +86,17 @@ ScopeView {
95 target: dashContent
86 target: dashContent
96 onScopeLoaded: switch (scopeId) {
87 onScopeLoaded: switch (scopeId) {
97 case "mockmusicmaster.scope":
88 case "mockmusicmaster.scope":
98− musicFilter.model = dashContent.scopes.get("mockmusicmaster.scope").results
89+ musicRepeater.model = dashContent.scopes.get("mockmusicmaster.scope").categories
99 break;
90 break;
100 case "mockvideosmaster.scope":
91 case "mockvideosmaster.scope":
101− videosFilter.model = dashContent.scopes.get("mockvideosmaster.scope").results
92+ videosRepeater.model = dashContent.scopes.get("mockvideosmaster.scope").categories
102 break;
93 break;
103 }
94 }
104 }
95 }
105
96
106 property var categoryModels: {"AppsModel": appsModel,
97 property var categoryModels: {"AppsModel": appsModel,
107− "FavouriteModel": favouritesFilter,
108− "RecentModel": recentFilter,
109− "MusicModel": musicFilter,
98+ "MusicModel": musicModel,
110− "VideosModel": videosFilter,
99+ "VideosModel": videosModel,
111 }
100 }
112
101
113 ScopeListView {
102 ScopeListView {
@@ -127,7 +116,7 @@ ScopeView {
127 anchors { top: parent.top; left: parent.left; right: parent.right }
116 anchors { top: parent.top; left: parent.left; right: parent.right }
128 source: component
117 source: component
129 onLoaded: {
118 onLoaded: {
130− item.model = categoryModels[modelName]
119+ item.model = Qt.binding(function() { return categoryModels[modelName]; });
131
120
132 //FIXME: workaround for lack of previews for videos in Home scope.
121 //FIXME: workaround for lack of previews for videos in Home scope.
133 //Need to connect to the clicked() signal here and act upon it here instead.
122 //Need to connect to the clicked() signal here and act upon it here instead.
Dash/DashVideos.qml+2−2
@@ -120,8 +120,8 @@ ScopeView {
120 // VideosCarousel and VideosFilterGrid have different
120 // VideosCarousel and VideosFilterGrid have different
121 // clicked signals, accomodate for that
121 // clicked signals, accomodate for that
122 if (categoryId == 1) {
122 if (categoryId == 1) {
123− var fileUri = delegateItem.model.column_0.replace(/^[^:]+:/, "")
123+ var fileUri = delegateItem.model.uri.replace(/^[^:]+:/, "")
124− dataItem = {fileUri: fileUri, nfoUri: delegateItem.model.column_6}
124+ dataItem = {fileUri: fileUri, nfoUri: delegateItem.model.comment}
125 } else {
125 } else {
126 dataItem = data;
126 dataItem = data;
127 }
127 }
Dash/Generic/GenericPreview.qmlnew file+84
@@ -0,0 +1,84 @@
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 "../../Components/IconUtil.js" as IconUtil
22+import ".."
23+
24+DashPreview {
25+ id: genericPreview
26+ property var previewData
27+
28+ title: previewData.title
29+ url: IconUtil.from_gicon(previewData.image)
30+ previewWidthRatio: 0.6
31+
32+ buttons: GridView {
33+ id: buttons
34+ model: genericPreview.previewData.actions
35+
36+ property int numOfRows: (count + 1) / 2
37+ property int spacing: units.gu(1)
38+ height: Math.max(units.gu(4), units.gu(4)*numOfRows + spacing*(numOfRows - 1))
39+
40+ cellWidth: Math.max(units.gu(9), width / 2)
41+ cellHeight: buttonHeight + spacing
42+ property int buttonWidth: Math.max(0, width / 2 - spacing)
43+ property int buttonHeight: units.gu(4)
44+
45+ delegate: Button {
46+ width: Math.max(units.gu(4), buttons.buttonWidth)
47+ height: buttons.buttonHeight
48+ color: "#dd4814"
49+ text: modelData.displayName
50+ iconSource: modelData.iconHint
51+ iconPosition: "right"
52+ visible: true
53+ onClicked: {
54+ genericPreview.previewData.execute(modelData.id, { })
55+ }
56+ }
57+ focus: false
58+ }
59+ description: Column {
60+ spacing: units.gu(2)
61+
62+ Label {
63+ visible: text != ""
64+ fontSize: "medium"
65+ opacity: 0.6
66+ color: "white"
67+ text: previewData.subtitle
68+ style: Text.Raised
69+ styleColor: "black"
70+ wrapMode: Text.WordWrap
71+ }
72+
73+ Label {
74+ visible: text != ""
75+ fontSize: "small"
76+ opacity: 0.6
77+ color: "white"
78+ text: previewData.description
79+ style: Text.Raised
80+ styleColor: "black"
81+ wrapMode: Text.WordWrap
82+ }
83+ }
84+}
Dash/GenericScopeView.qml+121−2
@@ -22,6 +22,7 @@ import "../Components/IconUtil.js" as IconUtil
22
22
23ScopeView {
23ScopeView {
24 id: scopeView
24 id: scopeView
25+ property alias previewShown: previewLoader.onScreen
25
26
26 onIsCurrentChanged: {
27 onIsCurrentChanged: {
27 pageHeader.resetSearch();
28 pageHeader.resetSearch();
@@ -47,6 +48,8 @@ ScopeView {
47 id: categoryView
48 id: categoryView
48 anchors.fill: parent
49 anchors.fill: parent
49 model: scopeView.categories
50 model: scopeView.categories
51+ forceNoClip: previewLoader.onScreen
52+
50 onAtYEndChanged: if (atYEnd) endReached()
53 onAtYEndChanged: if (atYEnd) endReached()
51 onMovingChanged: if (moving && atYEnd) endReached()
54 onMovingChanged: if (moving && atYEnd) endReached()
52
55
@@ -72,10 +75,35 @@ ScopeView {
72 delegate: Tile {
75 delegate: Tile {
73 width: filtergrid.cellWidth
76 width: filtergrid.cellWidth
74 height: filtergrid.cellHeight
77 height: filtergrid.cellHeight
75− text: column_5 ? column_5 : "" // FIXME: this shouldn't be necessary
78+ text: title
76 imageWidth: units.gu(11)
79 imageWidth: units.gu(11)
77 imageHeight: units.gu(16)
80 imageHeight: units.gu(16)
81+
78− source: column_1 ? IconUtil.from_gicon(column_1) : "" // FIXME: ditto
82+ source: IconUtil.from_gicon(icon)
83+
84+ MouseArea {
85+ anchors {
86+ fill: parent
87+ }
88+ onClicked: {
89+ mouse.accepted = true
90+ effect.positionPx = mapToItem(categoryView, 0, 0).y
91+ scopeView.scope.activate(uri, icon,
92+ category, 0,
93+ mimetype, title,
94+ comment, dndUri,
95+ metadata)
96+ }
97+ onPressAndHold: {
98+ mouse.accepted = true
99+ effect.positionPx = mapToItem(categoryView, 0, 0).y
100+ scopeView.scope.preview(uri, icon,
101+ category, 0,
102+ mimetype, title,
103+ comment, dndUri,
104+ metadata)
105+ }
106+ }
79 }
107 }
80 }
108 }
81 }
109 }
@@ -93,4 +121,95 @@ ScopeView {
93 searchEntryEnabled: true
121 searchEntryEnabled: true
94 }
122 }
95 }
123 }
124+
125+ OpenEffect {
126+ id: effect
127+ anchors {
128+ fill: parent
129+ bottomMargin: -bottomOverflow
130+ }
131+ sourceItem: categoryView
132+
133+ enabled: gap > 0.0
134+
135+ topGapPx: (1 - gap) * positionPx
136+ topOpacity: (1 - gap * 1.2)
137+ bottomGapPx: positionPx + gap * (targetBottomGapPx - positionPx)
138+ bottomOverflow: units.gu(20)
139+ bottomOpacity: 1 - (gap * 0.8)
140+
141+ property int targetBottomGapPx: height - units.gu(8) - bottomOverflow
142+ property real gap: previewLoader.open ? 1.0 : 0.0
143+
144+ Behavior on gap {
145+ NumberAnimation {
146+ duration: 200
147+ easing.type: Easing.InOutQuad
148+ onRunningChanged: {
149+ if (!previewLoader.open && !running) {
150+ previewLoader.onScreen = false
151+ }
152+ }
153+ }
154+ }
155+ }
156+
157+ Connections {
158+ target: scopeView.scope
159+ onPreviewReady: {
160+ previewLoader.previewData = preview
161+ previewLoader.open = true
162+ }
163+ }
164+
165+ PreviewDelegateMapper {
166+ id: previewDelegateMapper
167+ }
168+
169+ Connections {
170+ ignoreUnknownSignals: true
171+ target: previewLoader.valid ? previewLoader.item : null
172+ onClose: {
173+ previewLoader.open = false
174+ }
175+ }
176+
177+ Loader {
178+ id: previewLoader
179+ property var previewData
180+ height: effect.bottomGapPx - effect.topGapPx
181+ anchors {
182+ top: parent.top
183+ topMargin: effect.topGapPx
184+ left: parent.left
185+ right: parent.right
186+ }
187+ source: onScreen ? previewDelegateMapper.map(previewLoader.previewData.rendererName) : ""
188+
189+ property bool open: false
190+ property bool onScreen: false
191+ property bool valid: item !== null
192+
193+ onOpenChanged: {
194+ if (open) {
195+ onScreen = true
196+ }
197+ }
198+
199+ onLoaded: {
200+ item.previewData = previewLoader.previewData
201+ }
202+ }
203+
204+ // TODO: Move as InverseMouseArea to DashPreview
205+ MouseArea {
206+ enabled: previewLoader.onScreen
207+ anchors {
208+ fill: parent
209+ topMargin: effect.bottomGapPx
210+ }
211+ onClicked: {
212+ previewLoader.open = false;
213+ }
214+ }
96}
215}
Dash/Music/CarouselDelegateMusic.qml+1−1
@@ -28,7 +28,7 @@ BaseCarouselDelegate {
28 image: Image {
28 image: Image {
29 asynchronous: true
29 asynchronous: true
30 sourceSize { width: item.width; height: item.height }
30 sourceSize { width: item.width; height: item.height }
31− source: model ? model.column_1 : ""
31+ source: model ? model.icon : ""
32 }
32 }
33 }
33 }
34
34
Dash/Music/MusicFilterGrid.qml+3−3
@@ -38,9 +38,9 @@ FilterGrid {
38 height: filterGrid.cellHeight
38 height: filterGrid.cellHeight
39 iconWidth: filterGrid.iconWidth
39 iconWidth: filterGrid.iconWidth
40 iconHeight: filterGrid.iconHeight
40 iconHeight: filterGrid.iconHeight
41− artist: model.column_5
41+ artist: model.title
42− album: model.column_6
42+ album: model.comment
43− source: model.column_1
43+ source: model.icon
44 onClicked: {
44 onClicked: {
45 filterGrid.clicked(index);
45 filterGrid.clicked(index);
46 }
46 }
Launcher/ShortcutsContainer.qml → Dash/PreviewDelegateMapper.qmlrenamed+13−18
@@ -16,24 +16,19 @@
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18
18
19−Column {
19+QtObject {
20− id: shortcutsContainer
20+ property var d: QtObject {
21−
21+ readonly property string genericPreview: "Generic/GenericPreview.qml"
22− property int foldedAngle: 0
22+ property var previewDelegateMapping: {"preview-generic": genericPreview,
23− property int initialFoldedOffset: 0
23+ }
24− property int foldedOffset: 0
24+ }
25− property int initialIndex: 0
26−
27− property bool animating: angleAnimation.running || offsetAnimation.running
28−
29− property ListModel model
30− property var delegate
31−
32− Behavior on foldedAngle { NumberAnimation { id: angleAnimation; duration: 200; } }
33− Behavior on foldedOffset { NumberAnimation { id: offsetAnimation; duration: 200; } }
34
25
35− Repeater {
26+ function map(rendererName) {
36− model: shortcutsContainer.model
27+ var customPreview = d.previewDelegateMapping[rendererName]
37− delegate: shortcutsContainer.delegate
28+ if (customPreview != undefined) {
29+ return customPreview
30+ }
31+ console.debug("Renderer "+rendererName+" not found, using preview-generic")
32+ return d.genericPreview
38 }
33 }
39}
34}
Dash/Video/CarouselDelegateVideo.qml+1−1
@@ -28,7 +28,7 @@ BaseCarouselDelegate {
28 image: Image {
28 image: Image {
29 asynchronous: true
29 asynchronous: true
30 sourceSize { width: item.width; height: item.height }
30 sourceSize { width: item.width; height: item.height }
31− source: model ? model.column_1 : ""
31+ source: model ? model.icon : ""
32 }
32 }
33 }
33 }
34
34
Dash/Video/VideosFilterGrid.qml+4−4
@@ -37,14 +37,14 @@ FilterGrid {
37 objectName: "delegate" + index
37 objectName: "delegate" + index
38 width: filtergrid.cellWidth
38 width: filtergrid.cellWidth
39 height: filtergrid.cellHeight
39 height: filtergrid.cellHeight
40− text: model.column_5
40+ text: model.title
41 imageWidth: filtergrid.iconWidth
41 imageWidth: filtergrid.iconWidth
42 imageHeight: filtergrid.iconHeight
42 imageHeight: filtergrid.iconHeight
43− source: model.column_1
43+ source: model.icon
44 fillMode: Image.PreserveAspectCrop
44 fillMode: Image.PreserveAspectCrop
45 onClicked: {
45 onClicked: {
46− var fileUri = model.column_0.replace(/^[^:]+:/, "")
46+ var fileUri = model.uri.replace(/^[^:]+:/, "")
47− var data = {fileUri: fileUri, nfoUri: model.column_6}
47+ var data = {fileUri: fileUri, nfoUri: model.comment}
48 filtergrid.clicked(index, data, tile.y);
48 filtergrid.clicked(index, data, tile.y);
49 }
49 }
50 }
50 }
Launcher/Launcher.qml+2−5
@@ -19,6 +19,7 @@ import "../Components"
19import Ubuntu.Components 0.1
19import Ubuntu.Components 0.1
20import Ubuntu.Gestures 0.1
20import Ubuntu.Gestures 0.1
21import Unity 0.1
21import Unity 0.1
22+import Unity.Launcher 0.1
22
23
23Item {
24Item {
24 id: root
25 id: root
@@ -96,10 +97,6 @@ Item {
96 }
97 }
97 }
98 }
98
99
99− LauncherModel {
100− id: launcherModel
101− }
102−
103 MouseArea {
100 MouseArea {
104 id: launcherDragArea
101 id: launcherDragArea
105 enabled: root.state == "visible"
102 enabled: root.state == "visible"
@@ -152,7 +149,7 @@ Item {
152 bottom: parent.bottom
149 bottom: parent.bottom
153 }
150 }
154 x: -width
151 x: -width
155− model: launcherModel
152+ model: LauncherModel
156
153
157 property bool animate: true
154 property bool animate: true
158
155
Launcher/LauncherPanel.qml+4−2
@@ -17,6 +17,7 @@
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19import Unity 0.1
19import Unity 0.1
20+import Unity.Launcher 0.1
20import "../Components/ListItems"
21import "../Components/ListItems"
21
22
22Item {
23Item {
@@ -83,6 +84,7 @@ Item {
83 height: width
84 height: width
84 anchors.centerIn: parent
85 anchors.centerIn: parent
85 source: "graphics/home.png"
86 source: "graphics/home.png"
87+ rotation: root.rotation
86 }
88 }
87 }
89 }
88 ThinDivider {
90 ThinDivider {
@@ -139,7 +141,7 @@ Item {
139 } else if (angle < -12) {
141 } else if (angle < -12) {
140 launcherListView.flick(0, launcherListView.clickFlickSpeed);
142 launcherListView.flick(0, launcherListView.clickFlickSpeed);
141 } else {
143 } else {
142− root.applicationSelected(launcherModel.get(index).desktopFile);
144+ root.applicationSelected(LauncherModel.get(index).desktopFile);
143 }
145 }
144 return;
146 return;
145 }
147 }
@@ -150,7 +152,7 @@ Item {
150 } else if (angle < -30) {
152 } else if (angle < -30) {
151 launcherListView.flick(0, launcherListView.clickFlickSpeed);
153 launcherListView.flick(0, launcherListView.clickFlickSpeed);
152 } else {
154 } else {
153− root.applicationSelected(launcherModel.get(index).desktopFile);
155+ root.applicationSelected(LauncherModel.get(index).desktopFile);
154 }
156 }
155 }
157 }
156 }
158 }
Panel/Indicators/NetworkIndicatorPage.qml+1−2
@@ -49,7 +49,6 @@ PageStack {
49
49
50 ICNetwork.PasswordPage {
50 ICNetwork.PasswordPage {
51 agent: networkAgent
51 agent: networkAgent
52− token: token
53 }
52 }
54 }
53 }
55
54
@@ -57,7 +56,7 @@ PageStack {
57 id: networkAgent
56 id: networkAgent
58
57
59 onSecretRequested: {
58 onSecretRequested: {
60− _network.push(passwordPageComponent);
59+ _network.push(passwordPageComponent, {"token": token});
61 }
60 }
62 }
61 }
63
62
Shell.qml−3
@@ -263,9 +263,6 @@ FocusScope {
263 function show() {
263 function show() {
264 stages.show();
264 stages.show();
265 }
265 }
266− function showWithoutAnimation() {
267− stages.showWithoutAnimation();
268− }
269 function hide() {
266 function hide() {
270 }
267 }
271
268
build+2−6
@@ -36,16 +36,12 @@ BUILD_TYPE="debug"
36[ $# -eq 1 ] && BUILD_TYPE="$1"
36[ $# -eq 1 ] && BUILD_TYPE="$1"
37
37
38install_dependencies() {
38install_dependencies() {
39− [ -f /etc/apt/sources.list.d/phablet-team-desktop-deps-${DISTRIB_CODENAME}.list ] || sudo add-apt-repository ppa:phablet-team/desktop-deps || exit 1
39+ [ -f /etc/apt/sources.list.d/ubuntu-unity-next-${DISTRIB_CODENAME}.list ] || sudo add-apt-repository ppa:ubuntu-unity/next || exit 1
40− [ -f /etc/apt/sources.list.d/canonical-qt5-edgers-qt5-proper-${DISTRIB_CODENAME}.list ] || sudo add-apt-repository ppa:canonical-qt5-edgers/qt5-proper || exit 2;
41− [ -f /etc/apt/sources.list.d/ubuntu-sdk-team-ppa-${DISTRIB_CODENAME}.list ] || sudo add-apt-repository ppa:ubuntu-sdk-team/ppa || exit 3
42 sudo apt-get update || exit 4
40 sudo apt-get update || exit 4
43 echo "Installing Unity 8 dependencies.."
41 echo "Installing Unity 8 dependencies.."
44 sudo apt-get install devscripts \
42 sudo apt-get install devscripts \
45 equivs \
43 equivs \
46− libnm-glib-dev \
44+ qmenumodel-qml \
47− libnm-util-dev \
48− libqmenumodel-dev \
49 qtdeclarative5-ubuntu-ui-toolkit-plugin \
45 qtdeclarative5-ubuntu-ui-toolkit-plugin \
50 qtdeclarative5-dee-plugin \
46 qtdeclarative5-dee-plugin \
51 ubuntu-mobile-icons \
47 ubuntu-mobile-icons \
cmake/modules/Plugins.cmakenew file+48
@@ -0,0 +1,48 @@
1+# Creates targets for copying and installing qmlfiles and generating the qmltypes file for a plugin
2+#
3+# export_qmlplugin(plugin version sub_path [TARGETS target1 [target2 ...]])
4+#
5+# TARGETS additional install targets (eg the plugin shared object)
6+#
7+# Two targets will be created:
8+# - plugin-qmlfiles - Copies the qml files (*.qml, *.js, qmldir) into the shadow build folder.
9+# - plugin-qmltypes - Generates the qmltypes file in the shadow build folder.
10+
11+
12+macro(export_qmlplugin PLUGIN VERSION PLUGIN_SUBPATH)
13+ set(multi_value_keywords TARGETS)
14+ cmake_parse_arguments(qmlplugin "" "" "${multi_value_keywords}" ${ARGN})
15+
16+ file(GLOB QMLFILES
17+ *.qml
18+ *.js
19+ qmldir
20+ )
21+
22+ # copy the qmldir file
23+ add_custom_target(${PLUGIN}-qmlfiles ALL
24+ COMMAND cp ${QMLFILES} ${CMAKE_BINARY_DIR}/plugins/${PLUGIN_SUBPATH}
25+ DEPENDS ${QMLFILES}
26+ )
27+
28+ # create the plugin.qmltypes file
29+ add_custom_target(${PLUGIN}-qmltypes ALL
30+ COMMAND qmlplugindump -notrelocatable ${PLUGIN} ${VERSION} ${CMAKE_BINARY_DIR}/plugins > ${CMAKE_BINARY_DIR}/plugins/${PLUGIN_SUBPATH}/plugin.qmltypes
31+ )
32+ add_dependencies(${PLUGIN}-qmltypes ${PLUGIN}-qmlfiles ${qmlplugin_TARGETS})
33+
34+ # install the qmldir file.
35+ install(FILES ${QMLFILES}
36+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/${PLUGIN_SUBPATH}
37+ )
38+
39+ # install the qmltypes file.
40+ install(FILES ${CMAKE_BINARY_DIR}/plugins/${PLUGIN_SUBPATH}/plugin.qmltypes
41+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/${PLUGIN_SUBPATH}
42+ )
43+
44+ # install the additional targets
45+ install(TARGETS ${qmlplugin_TARGETS}
46+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/${PLUGIN_SUBPATH}
47+ )
48+endmacro(export_qmlplugin)
cmake/modules/autopilot.cmake+7−4
@@ -1,7 +1,10 @@
1add_custom_target(autopilot)
1add_custom_target(autopilot)
2
2
3−function(declare_autopilot_test TEST_NAME WORKING_DIR)
3+function(declare_autopilot_test TEST_NAME TEST_SUITE WORKING_DIR)
4− add_custom_command(TARGET autopilot
4+ add_custom_target(autopilot-${TEST_NAME}
5− COMMAND autopilot run ${TEST_NAME}
5+ COMMAND autopilot run ${TEST_SUITE}
6− WORKING_DIRECTORY ${WORKING_DIR})
6+ WORKING_DIRECTORY ${WORKING_DIR}
7+ )
8+
9+ add_dependencies(autopilot autopilot-${TEST_NAME})
7endfunction()
10endfunction()
debian/changelog+103
@@ -1,3 +1,106 @@
1+unity8 (7.81.3+13.10.20130716ubuntu.unity.next-0ubuntu1) saucy; urgency=low
2+
3+ [ Pete Woods ]
4+ * Rename the demo user "single" to "phablet" Fix the infographics on
5+ the device At the moment the mock lightdm backend we are using says
6+ the current user is called "single", while in reality the processes
7+ all run as the "phablet" user.
8+
9+ [ Michał Sawicz ]
10+ * Only use ppa:ubuntu-unity/next and clean build scripts and CODING,
11+ accordingly.
12+ * Do not recommend indicator-power and indicator-sound. On device
13+ they're provided by lp:indicator-server for the time being.
14+ * Fix the Network page to provide the correct token. (LP: #1201529)
15+
16+ [ Ubuntu daily release ]
17+ * Automatic snapshot from revision 109 (ubuntu-unity/next)
18+
19+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 16 Jul 2013 02:32:03 +0000
20+
21+unity8 (7.81.3+13.10.20130714ubuntu.unity.next-0ubuntu1) saucy; urgency=low
22+
23+ [ Michael Terry ]
24+ * Change Ok to OK. (LP: #1131842)
25+
26+ [ Ubuntu daily release ]
27+ * Automatic snapshot from revision 104 (ubuntu-unity/next)
28+
29+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Sun, 14 Jul 2013 02:31:57 +0000
30+
31+unity8 (7.81.3+13.10.20130712ubuntu.unity.next-0ubuntu1) saucy; urgency=low
32+
33+ [ Michael Zanetti ]
34+ * Make use of the launcher API defined in unity-api and separate the
35+ model from the backend.
36+
37+ [ Michał Sawicz ]
38+ * Issue wrap-and-sort -abt on debian/.
39+
40+ [ Nick Dedekind ]
41+ * Moved indicators-client code into unity8. (LP: #1191132, #1191822)
42+
43+ [ Ubuntu daily release ]
44+ * Automatic snapshot from revision 102 (ubuntu-unity/next)
45+
46+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Fri, 12 Jul 2013 02:31:59 +0000
47+
48+unity8 (7.81.3+13.10.20130711ubuntu.unity.next-0ubuntu1) saucy; urgency=low
49+
50+ [ Michael Zanetti ]
51+ * invert the home button too in case the whole panel is inverted. (LP:
52+ #1199622)
53+
54+ [ Michał Sawicz ]
55+ * Make the OpenEffect non-live by default to improve performance. (LP:
56+ #1124584)
57+
58+ [ Ying-Chun Liu ]
59+ * Add Generic Preview. Modify GenericScopeView to support activate and
60+ preview.
61+
62+ [ Ubuntu daily release ]
63+ * Automatic snapshot from revision 98 (ubuntu-unity/next)
64+
65+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Thu, 11 Jul 2013 03:00:53 +0000
66+
67+unity8 (7.81.3+13.10.20130710ubuntu.unity.next-0ubuntu1) saucy; urgency=low
68+
69+ [ Michael Zanetti ]
70+ * removed unused old file ShortcutsContainer.qml.
71+
72+ [ Michał Sawicz ]
73+ * Fix fetching data from scopes in the custom scope pages. (LP:
74+ #1199322)
75+
76+ [ Ying-Chun Liu ]
77+ * Fix references to scope data. (LP: #1199322)
78+
79+ [ Albert Astals ]
80+ * Fix showHeader animation when the header is half shown at top .
81+ * Disable -pedantic on the private Qt headers .
82+
83+ [ Pawel Stolowski ]
84+ * Bindings for SocialPreview.
85+
86+ [ Ubuntu daily release ]
87+ * Automatic snapshot from revision 94 (ubuntu-unity/next)
88+
89+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 10 Jul 2013 02:32:00 +0000
90+
91+unity8 (7.81.3+13.10.20130709ubuntu.unity.next-0ubuntu1) saucy; urgency=low
92+
93+ [ Michal Hruby ]
94+ * Implement CategoryResults based on DeeFilterModel.
95+
96+ [ Nick Dedekind ]
97+ * Added plugin cmake procedure for qmltypes files.
98+
99+ [ Ubuntu daily release ]
100+ * Automatic snapshot from revision 86 (ubuntu-unity/next)
101+
102+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 09 Jul 2013 02:58:58 +0000
103+
1unity8 (7.81.3+13.10.20130708ubuntu.unity.next-0ubuntu1) saucy; urgency=low
104unity8 (7.81.3+13.10.20130708ubuntu.unity.next-0ubuntu1) saucy; urgency=low
2
105
3 [ Michael Terry ]
106 [ Michael Terry ]
debian/control+42−37
@@ -15,6 +15,7 @@ Build-Depends: cmake,
15 libpulse-dev,
15 libpulse-dev,
16 libqmenumodel-dev,
16 libqmenumodel-dev,
17 libqt5v8-5-private-dev,
17 libqt5v8-5-private-dev,
18+ libunity-api-dev (>= 7.80.3),
18 libunity-core-6.0-dev (<< 7.80),
19 libunity-core-6.0-dev (<< 7.80),
19 libunity-dev (>= 7.0.3),
20 libunity-dev (>= 7.0.3),
20 libunity-scopes-json-def-phone,
21 libunity-scopes-json-def-phone,
@@ -34,7 +35,7 @@ Build-Depends: cmake,
34 qtdeclarative5-test-plugin,
35 qtdeclarative5-test-plugin,
35 qtdeclarative5-ubuntu-ui-toolkit-plugin,
36 qtdeclarative5-ubuntu-ui-toolkit-plugin,
36 qtdeclarative5-xmllistmodel-plugin,
37 qtdeclarative5-xmllistmodel-plugin,
37− ttf-ubuntu-font-family
38+ ttf-ubuntu-font-family,
38Standards-Version: 3.9.4
39Standards-Version: 3.9.4
39Homepage: http://launchpad.net/unity
40Homepage: http://launchpad.net/unity
40# If you aren't a member of ~unity-team but need to upload
41# If you aren't a member of ~unity-team but need to upload
@@ -43,6 +44,16 @@ Homepage: http://launchpad.net/unity
43Vcs-Bzr: https://code.launchpad.net/unity8
44Vcs-Bzr: https://code.launchpad.net/unity8
44Vcs-Browser: https://bazaar.launchpad.net/~unity-team/unity8/trunk
45Vcs-Browser: https://bazaar.launchpad.net/~unity-team/unity8/trunk
45
46
47+Package: indicators-client
48+Architecture: amd64 armhf i386
49+Depends: qmenumodel-qml,
50+ qtdeclarative5-ubuntu-ui-toolkit-plugin | qt-components-ubuntu,
51+ unity8 (= ${binary:Version}),
52+ ${misc:Depends},
53+ ${shlibs:Depends},
54+Description: Indicators client test application
55+ This package contains the client application for indicators used by autopilot
56+
46Package: unity8
57Package: unity8
47Architecture: any
58Architecture: any
48Depends: qmenumodel-qml,
59Depends: qmenumodel-qml,
@@ -50,51 +61,20 @@ Depends: qmenumodel-qml,
50 qtdeclarative5-ubuntu-ui-toolkit-plugin,
61 qtdeclarative5-ubuntu-ui-toolkit-plugin,
51 qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
62 qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
52 qtdeclarative5-xmllistmodel-plugin,
63 qtdeclarative5-xmllistmodel-plugin,
64+ unity-launcher-impl-2,
53 unity-notifications-impl-1,
65 unity-notifications-impl-1,
54 unity8-fake-env | qtubuntu-shell,
66 unity8-fake-env | qtubuntu-shell,
55 unity8-private (= ${binary:Version}),
67 unity8-private (= ${binary:Version}),
68+ unity8-private | unity-launcher-impl,
56 ${misc:Depends},
69 ${misc:Depends},
57− ${shlibs:Depends}
70+ ${shlibs:Depends},
58Recommends: indicator-battery,
71Recommends: indicator-battery,
59 indicator-messages,
72 indicator-messages,
60− indicator-network,
61− indicator-sound,
62 indicator-time,
73 indicator-time,
63− ${unity-default-masterscopes}
74+ ${unity-default-masterscopes},
64Description: Unity 8 shell
75Description: Unity 8 shell
65 The Unity 8 shell is the primary user interface for Ubuntu devices.
76 The Unity 8 shell is the primary user interface for Ubuntu devices.
66
77
67−Package: unity8-private
68−Architecture: any
69−Multi-Arch: same
70−Pre-Depends: ${misc:Pre-Depends}
71−Depends: ${misc:Depends}, ${shlibs:Depends}
72−Description: Unity 8 private libs
73− The Unity 8 shell is the primary user interface for Ubuntu devices.
74− .
75− This package contains the private libraries for QML and other components
76− only used by the shell.
77−
78−Package: unity8-fake-env
79−Architecture: any
80−Multi-Arch: same
81−Pre-Depends: ${misc:Pre-Depends}
82−Depends: ${misc:Depends}, ${shlibs:Depends}
83−Provides: qtubuntu-shell
84−Description: Fake environment for running Unity 8 shell
85− Provides fake implementations of some QML modules used by Unity 8 shell
86− (e.g Ubuntu.Application) so that you can run it in a sandboxed environment.
87−
88−Package: indicators-client
89−Architecture: amd64 armhf i386
90−Depends: qmenumodel-qml,
91− qtdeclarative5-ubuntu-ui-toolkit-plugin | qt-components-ubuntu,
92− unity8 (= ${binary:Version}),
93− ${misc:Depends},
94− ${shlibs:Depends}
95−Description: Indicators client test application
96− This package contains the client application for indicators used by autopilot
97−
98Package: unity8-autopilot
78Package: unity8-autopilot
99Architecture: all
79Architecture: all
100Depends: indicators-client (>= ${source:Version}),
80Depends: indicators-client (>= ${source:Version}),
@@ -106,6 +86,31 @@ Depends: indicators-client (>= ${source:Version}),
106 unity8-fake-env (>= ${source:Version}),
86 unity8-fake-env (>= ${source:Version}),
107 ${misc:Depends},
87 ${misc:Depends},
108 ${python:Depends},
88 ${python:Depends},
109− ${shlibs:Depends}
89+ ${shlibs:Depends},
110Description: Test package for Unity 8 shell
90Description: Test package for Unity 8 shell
111 Autopilot tests for the unity8 package
91 Autopilot tests for the unity8 package
92+
93+Package: unity8-fake-env
94+Architecture: any
95+Multi-Arch: same
96+Pre-Depends: ${misc:Pre-Depends},
97+Depends: ${misc:Depends},
98+ ${shlibs:Depends},
99+Provides: qtubuntu-shell,
100+Description: Fake environment for running Unity 8 shell
101+ Provides fake implementations of some QML modules used by Unity 8 shell
102+ (e.g Ubuntu.Application) so that you can run it in a sandboxed environment.
103+
104+Package: unity8-private
105+Architecture: any
106+Multi-Arch: same
107+Pre-Depends: ${misc:Pre-Depends},
108+Depends: ${misc:Depends},
109+ ${shlibs:Depends},
110+Provides: unity-launcher-impl,
111+ unity-launcher-impl-2,
112+Description: Unity 8 private libs
113+ The Unity 8 shell is the primary user interface for Ubuntu devices.
114+ .
115+ This package contains the private libraries for QML and other components
116+ only used by the shell.
debian/unity8-autopilot.install−1
@@ -1,2 +1 @@
1−usr/lib/python*/*/indicators_client
2usr/lib/python*/*/unity*
1usr/lib/python*/*/unity*
plugins/HudClient/CMakeLists.txt+5−12
@@ -1,3 +1,6 @@
1+# export_qmlplugin macro
2+include(Plugins)
3+
1find_package(Qt5Core REQUIRED)
4find_package(Qt5Core REQUIRED)
2find_package(Qt5Quick REQUIRED)
5find_package(Qt5Quick REQUIRED)
3pkg_search_module(DEE dee-1.0 REQUIRED)
6pkg_search_module(DEE dee-1.0 REQUIRED)
@@ -35,15 +38,5 @@ target_link_libraries(HudClientQml
35
38
36qt5_use_modules(HudClientQml Qml)
39qt5_use_modules(HudClientQml Qml)
37
40
38−# copy qmldir file into build directory for shadow builds
41+# export the qmldir and qmltypes files
39−file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
40− DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
41− )
42−
43−install(TARGETS HudClientQml
42+export_qmlplugin(HudClient 0.1 HudClient TARGETS HudClientQml)
44− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/HudClient
45− )
46−
47−install(FILES qmldir
48− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/HudClient
49− )
plugins/HudClient/qmldir+1
@@ -1 +1,2 @@
1plugin HudClientQml
1plugin HudClientQml
2+typeinfo plugin.qmltypes
plugins/LightDM/CMakeLists.txt+5−12
@@ -1,3 +1,6 @@
1+# export_qmlplugin macro
2+include(Plugins)
3+
1# Dependencies
4# Dependencies
2include(FindPkgConfig)
5include(FindPkgConfig)
3pkg_check_modules(LIBUSERMETRICSOUTPUT REQUIRED libusermetricsoutput-1)
6pkg_check_modules(LIBUSERMETRICSOUTPUT REQUIRED libusermetricsoutput-1)
@@ -32,15 +35,5 @@ target_link_libraries(LightDM-qml
32
35
33qt5_use_modules(LightDM-qml Gui Qml)
36qt5_use_modules(LightDM-qml Gui Qml)
34
37
35−# copy qmldir file into build directory for shadow builds
38+# export the qmldir and qmltypes files
36−file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
37− DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
38− )
39−
40−install(TARGETS LightDM-qml
39+export_qmlplugin(LightDM 0.1 LightDM TARGETS LightDM-qml)
41− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/LightDM
42− )
43−
44−install(FILES qmldir
45− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/LightDM
46− )
plugins/LightDM/qmldir+1
@@ -1,2 +1,3 @@
1module LightDM
1module LightDM
2plugin LightDM-qml
2plugin LightDM-qml
3+typeinfo plugin.qmltypes
plugins/ListViewWithPageHeader/CMakeLists.txt+5−12
@@ -1,3 +1,6 @@
1+# export_qmlplugin macro
2+include(Plugins)
3+
1# There's no cmake var for v8 include path :-/
4# There's no cmake var for v8 include path :-/
2# so create one
5# so create one
3LIST(GET Qt5Core_INCLUDE_DIRS 0 QtCoreDir0)
6LIST(GET Qt5Core_INCLUDE_DIRS 0 QtCoreDir0)
@@ -30,15 +33,5 @@ target_link_libraries(ListViewWithPageHeader-qml
30
33
31qt5_use_modules(ListViewWithPageHeader-qml Qml Quick)
34qt5_use_modules(ListViewWithPageHeader-qml Qml Quick)
32
35
33−# copy qmldir file into build directory for shadow builds
36+# export the qmldir and qmltypes files
34−file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
35− DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
36− )
37−
38−install(TARGETS ListViewWithPageHeader-qml
37+export_qmlplugin(ListViewWithPageHeader 0.1 ListViewWithPageHeader TARGETS ListViewWithPageHeader-qml)
39− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/ListViewWithPageHeader
40− )
41−
42−install(FILES qmldir
43− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/ListViewWithPageHeader
44− )
plugins/ListViewWithPageHeader/listviewwithpageheader.cpp+16
@@ -94,10 +94,13 @@
94#include <QDebug>
94#include <QDebug>
95#include <qqmlinfo.h>
95#include <qqmlinfo.h>
96#include <qqmlengine.h>
96#include <qqmlengine.h>
97+#pragma GCC diagnostic push
98+#pragma GCC diagnostic ignored "-pedantic"
97#include <private/qquickvisualdatamodel_p.h>
99#include <private/qquickvisualdatamodel_p.h>
98#include <private/qqmlglobal_p.h>
100#include <private/qqmlglobal_p.h>
99#include <private/qquickitem_p.h>
101#include <private/qquickitem_p.h>
100#include <private/qquickanimation_p.h>
102#include <private/qquickanimation_p.h>
103+#pragma GCC diagnostic pop
101// #include <private/qquickrectangle_p.h>
104// #include <private/qquickrectangle_p.h>
102
105
103static const qreal bufferRatio = 0.5;
106static const qreal bufferRatio = 0.5;
@@ -347,6 +350,19 @@ void ListViewWithPageHeader::showHeader()
347
350
348 auto to = qMax(-minYExtent(), contentY() - m_headerItem->height() + m_headerItemShownHeight);
351 auto to = qMax(-minYExtent(), contentY() - m_headerItem->height() + m_headerItemShownHeight);
349 if (to != contentY()) {
352 if (to != contentY()) {
353+ const bool headerShownByItsOwn = contentY() < m_headerItem->y() + m_headerItem->height();
354+ if (headerShownByItsOwn && m_headerItemShownHeight == 0) {
355+ // We are not clipping since we are just at the top of the viewport
356+ // but because of the showHeader animation we will need to, so
357+ // enable the clipping without logically moving the items
358+ m_headerItemShownHeight = m_headerItem->y() + m_headerItem->height() - contentY();
359+ if (!m_visibleItems.isEmpty()) {
360+ updateClipItem();
361+ ListItem *firstItem = m_visibleItems.first();
362+ firstItem->setY(firstItem->y() - m_headerItemShownHeight);
363+ layout();
364+ }
365+ }
350 m_headerShowAnimation->setTo(to);
366 m_headerShowAnimation->setTo(to);
351 m_headerShowAnimation->start();
367 m_headerShowAnimation->start();
352 }
368 }
plugins/ListViewWithPageHeader/listviewwithpageheader.h+3
@@ -17,8 +17,11 @@
17#ifndef LISTVIEWWITHPAGEHEADER_H
17#ifndef LISTVIEWWITHPAGEHEADER_H
18#define LISTVIEWWITHPAGEHEADER_H
18#define LISTVIEWWITHPAGEHEADER_H
19
19
20+#pragma GCC diagnostic push
21+#pragma GCC diagnostic ignored "-pedantic"
20#include <private/qquickitemchangelistener_p.h>
22#include <private/qquickitemchangelistener_p.h>
21#include <private/qquickflickable_p.h>
23#include <private/qquickflickable_p.h>
24+#pragma GCC diagnostic pop
22
25
23class QAbstractItemModel;
26class QAbstractItemModel;
24class QQuickChangeSet;
27class QQuickChangeSet;
plugins/ListViewWithPageHeader/qmldir+1
@@ -1,2 +1,3 @@
1module ListViewWithPageHeader
1module ListViewWithPageHeader
2plugin ListViewWithPageHeader-qml
2plugin ListViewWithPageHeader-qml
3+typeinfo plugin.qmltypes
plugins/Ubuntu/Gestures/CMakeLists.txt+5−13
@@ -1,3 +1,6 @@
1+# export_qmlplugin macro
2+include(Plugins)
3+
1set(CMAKE_AUTOMOC ON)
4set(CMAKE_AUTOMOC ON)
2
5
3include(FindPkgConfig)
6include(FindPkgConfig)
@@ -20,16 +23,5 @@ qt5_use_modules(UbuntuGestureQml Core Quick)
20# So that Foo.cpp can #include "Foo.moc"
23# So that Foo.cpp can #include "Foo.moc"
21include_directories(${CMAKE_CURRENT_BINARY_DIR})
24include_directories(${CMAKE_CURRENT_BINARY_DIR})
22
25
23−# copy files into build directory for shadow builds
26+# export the qmldir and qmltypes files
24−add_custom_target(UbuntuGestureQmlDirFile ALL
25− COMMAND cp "${CMAKE_CURRENT_SOURCE_DIR}/qmldir" ${CMAKE_CURRENT_BINARY_DIR}
26− DEPENDS qmldir
27−)
28−
29−install(TARGETS UbuntuGestureQml
27+export_qmlplugin(Ubuntu.Gestures 0.1 Ubuntu/Gestures TARGETS UbuntuGestureQml)
30− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/Ubuntu/Gestures
31− )
32−
33−install(FILES qmldir
34− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/Ubuntu/Gestures
35− )
plugins/Ubuntu/Gestures/qmldir+1
@@ -1,2 +1,3 @@
1module Ubuntu.Gestures
1module Ubuntu.Gestures
2plugin UbuntuGestureQml
2plugin UbuntuGestureQml
3+typeinfo plugin.qmltypes
plugins/Unity/CMakeLists.txt+9−14
@@ -1,3 +1,6 @@
1+# export_qmlplugin macro
2+include(Plugins)
3+
1add_subdirectory(Indicators)
4add_subdirectory(Indicators)
2
5
3# Dependencies
6# Dependencies
@@ -14,14 +17,12 @@ include_directories(
14)
17)
15
18
16set(QMLPLUGIN_SRC
19set(QMLPLUGIN_SRC
17− ../Utils/qsortfilterproxymodelqml.cpp # FIXME evaluate a more generic approach for using other plugins
18 scope.cpp
20 scope.cpp
19 scopes.cpp
21 scopes.cpp
20 categories.cpp
22 categories.cpp
21− categoryfilter.cpp
23+ categoryresults.cpp
22 plugin.cpp
24 plugin.cpp
23 bottombarvisibilitycommunicatorshell.cpp
25 bottombarvisibilitycommunicatorshell.cpp
24− launchermodel.cpp
25 applicationpreview.cpp
26 applicationpreview.cpp
26 genericpreview.cpp
27 genericpreview.cpp
27 moviepreview.cpp
28 moviepreview.cpp
@@ -29,6 +30,8 @@ set(QMLPLUGIN_SRC
29 preview.cpp
30 preview.cpp
30 previewaction.cpp
31 previewaction.cpp
31 previewinfohint.cpp
32 previewinfohint.cpp
33+ socialpreview.cpp
34+ socialpreviewcomment.cpp
32 variantutils.cpp
35 variantutils.cpp
33 )
36 )
34
37
@@ -45,15 +48,7 @@ target_link_libraries(Unity-qml
45
48
46qt5_use_modules(Unity-qml Qml)
49qt5_use_modules(Unity-qml Qml)
47
50
48−# copy qmldir file into build directory for shadow builds
51+# export the qmldir and qmltypes files
49−file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
52+export_qmlplugin(Unity 0.1 Unity TARGETS Unity-qml)
50− DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
51− )
52
53
53−install(TARGETS Unity-qml
54+add_subdirectory(Launcher)
54− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/Unity
55− )
56−
57−install(FILES qmldir
58− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/Unity
59− )
plugins/Unity/Indicators/Network/qml/PasswordPage.qml+1−1
@@ -75,7 +75,7 @@ Page {
75 }
75 }
76
76
77 Button {
77 Button {
78− text: "Ok"
78+ text: "OK"
79 width: units.gu(10)
79 width: units.gu(10)
80 onClicked: {
80 onClicked: {
81 agent.authenticate(token, password.text);
81 agent.authenticate(token, password.text);
plugins/Unity/Indicators/qml/SliderMenuItem.qml+7−1
@@ -39,7 +39,13 @@ MenuItem {
39 // passed to QStateAction::updateState(…). The server chokes on
39 // passed to QStateAction::updateState(…). The server chokes on
40 // those values, complaining that they’re not of the right type…
40 // those values, complaining that they’re not of the right type…
41 minimumValue: menu.extra.canonical_min ? menu.extra.canonical_min * 1.000001 : 0.0000001
41 minimumValue: menu.extra.canonical_min ? menu.extra.canonical_min * 1.000001 : 0.0000001
42+ maximumValue: {
42− maximumValue: menu.extra.canonical_max ? menu.extra.canonical_max * 1.000001 : 0.9999999
43+ var maximum = menu.extra.canonical_max ? menu.extra.canonical_max * 1.000001 : 0.9999999
44+ if (maximum <= minimumValue) {
45+ return minimumValue + 1;
46+ }
47+ return maximum;
48+ }
43
49
44 // FIXME - to be deprecated in Ubuntu.Components.
50 // FIXME - to be deprecated in Ubuntu.Components.
45 // Use this to disable the label, since there is not way to do it on the component.
51 // Use this to disable the label, since there is not way to do it on the component.
plugins/Unity/Launcher/CMakeLists.txtnew file+27
@@ -0,0 +1,27 @@
1+include(FindPkgConfig)
2+pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=2)
3+
4+include_directories(
5+ ${CMAKE_CURRENT_SOURCE_DIR}
6+)
7+
8+set(QMLLAUNCHERPLUGIN_SRC
9+ plugin.cpp
10+ launchermodel.cpp
11+ launcheritem.cpp
12+ quicklistmodel.cpp
13+ common/quicklistentry.cpp
14+ backend/launcherbackend.cpp
15+ ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherItemInterface.h
16+ ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherModelInterface.h
17+ ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/QuickListModelInterface.h
18+ )
19+
20+add_library(UnityLauncher-qml MODULE
21+ ${QMLLAUNCHERPLUGIN_SRC}
22+ )
23+
24+qt5_use_modules(UnityLauncher-qml Qml)
25+
26+# export the qmldir and qmltypes files
27+export_qmlplugin(Unity.Launcher 0.1 Unity/Launcher TARGETS UnityLauncher-qml)
plugins/Unity/Launcher/backend/launcherbackend.cppnew file+145
@@ -0,0 +1,145 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Michael Zanetti <michael.zanetti@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 "launcherbackend.h"
21+
22+#include <QHash>
23+
24+LauncherBackend::LauncherBackend(QObject *parent):
25+ QObject(parent)
26+{
27+
28+ // TODO: load default pinned ones from default config, instead of hardcoding here...
29+
30+ m_storedApps <<
31+ QLatin1String("phone-app.desktop") <<
32+ QLatin1String("camera-app.desktop") <<
33+ QLatin1String("gallery-app.desktop") <<
34+ QLatin1String("facebook-webapp.desktop") <<
35+ QLatin1String("webbrowser-app.desktop") <<
36+ QLatin1String("twitter-webapp.desktop") <<
37+ QLatin1String("gmail-webapp.desktop") <<
38+ QLatin1String("ubuntu-weather-app.desktop") <<
39+ QLatin1String("notes-app.desktop") <<
40+ QLatin1String("ubuntu-calendar-app.desktop");
41+
42+ // TODO: get stuff from desktop files instead this hardcoded map
43+ m_displayNameMap.insert("phone-app.desktop", "Phone");
44+ m_displayNameMap.insert("camera-app.desktop", "Camera");
45+ m_displayNameMap.insert("gallery-app.desktop", "Gallery");
46+ m_displayNameMap.insert("facebook-webapp.desktop", "Facebook");
47+ m_displayNameMap.insert("webbrowser-app.desktop", "Browser");
48+ m_displayNameMap.insert("twitter-webapp.desktop", "Twitter");
49+ m_displayNameMap.insert("gmail-webapp.desktop", "GMail");
50+ m_displayNameMap.insert("ubuntu-weather-app.desktop", "Weather");
51+ m_displayNameMap.insert("notes-app.desktop", "Notes");
52+ m_displayNameMap.insert("ubuntu-calendar-app.desktop", "Calendar");
53+
54+ // TODO: get stuff from desktop files instead this hardcoded map
55+ m_iconMap.insert("phone-app.desktop", "phone-app");
56+ m_iconMap.insert("camera-app.desktop", "camera");
57+ m_iconMap.insert("gallery-app.desktop", "gallery");
58+ m_iconMap.insert("facebook-webapp.desktop", "facebook");
59+ m_iconMap.insert("webbrowser-app.desktop", "browser");
60+ m_iconMap.insert("twitter-webapp.desktop", "twitter");
61+ m_iconMap.insert("gmail-webapp.desktop", "gmail");
62+ m_iconMap.insert("ubuntu-weather-app.desktop", "weather");
63+ m_iconMap.insert("notes-app.desktop", "notepad");
64+ m_iconMap.insert("ubuntu-calendar-app.desktop", "calendar");
65+
66+}
67+
68+LauncherBackend::~LauncherBackend()
69+{
70+
71+}
72+
73+QStringList LauncherBackend::storedApplications() const
74+{
75+ return m_storedApps;
76+}
77+
78+void LauncherBackend::setStoredApplications(const QStringList &appIds)
79+{
80+ m_storedApps = appIds;
81+ // TODO: Cleanup pinned state from settings for apps not in list any more.
82+}
83+
84+QString LauncherBackend::desktopFile(const QString &appId) const
85+{
86+ // TODO: return real path instead of this hardcoded one
87+ return QLatin1String("/usr/share/applications/") + appId;
88+}
89+
90+QString LauncherBackend::displayName(const QString &appId) const
91+{
92+ return m_displayNameMap.value(appId);
93+}
94+
95+QString LauncherBackend::icon(const QString &appId) const
96+{
97+ return m_iconMap.value(appId);
98+}
99+
100+bool LauncherBackend::isPinned(const QString &appId) const
101+{
102+ // TODO: return app's pinned state from settings
103+ Q_UNUSED(appId)
104+ return true;
105+}
106+
107+void LauncherBackend::setPinned(const QString &appId, bool pinned)
108+{
109+ // TODO: Store pinned state in settings.
110+ Q_UNUSED(appId)
111+ Q_UNUSED(pinned)
112+}
113+
114+QList<QuickListEntry> LauncherBackend::quickList(const QString &appId) const
115+{
116+ // TODO: Get static (from .desktop file) and dynamic (from the app itself)
117+ // entries and return them here. Frontend related entries (like "Pin to launcher")
118+ // don't matter here. This is just the backend part.
119+ // TODO: emit quickListChanged() when the dynamic part changes
120+ Q_UNUSED(appId)
121+ return QList<QuickListEntry>();
122+}
123+
124+int LauncherBackend::progress(const QString &appId) const
125+{
126+ // TODO: Return value for progress emblem.
127+ // TODO: emit progressChanged() when this value changes.
128+ Q_UNUSED(appId)
129+ return -1;
130+}
131+
132+int LauncherBackend::count(const QString &appId) const
133+{
134+ // TODO: Return value for count emblem.
135+ // TODO: emit countChanged() when this value changes.
136+ Q_UNUSED(appId)
137+ return 0;
138+}
139+
140+void LauncherBackend::triggerQuickListAction(const QString &appId, const QString &quickListId)
141+{
142+ // TODO: execute the given quicklist action
143+ Q_UNUSED(appId)
144+ Q_UNUSED(quickListId)
145+}
plugins/Unity/Launcher/backend/launcherbackend.hnew file+132
@@ -0,0 +1,132 @@
1+/* Copyright (C) 2013 Canonical, Ltd.
2+ *
3+ * Authors:
4+ * Michael Zanetti <michael.zanetti@canonical.com>
5+ *
6+ * This program is free software; you can redistribute it and/or modify
7+ * it under the terms of the GNU General Public License as published by
8+ * the Free Software Foundation; version 3.
9+ *
10+ * This program is distributed in the hope that it will be useful,
11+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+ * GNU General Public License for more details.
14+ *
15+ * You should have received a copy of the GNU General Public License
16+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
17+ */
18+
19+#ifndef LAUNCHERBACKEND_H
20+#define LAUNCHERBACKEND_H
21+
22+#include "common/quicklistentry.h"
23+
24+#include <QObject>
25+#include <QStringList>
26+#include <QHash>
27+
28+/**
29+ * @brief An interface that provides all the data needed by the launcher.
30+ */
31+
32+class LauncherBackend : public QObject
33+{
34+ Q_OBJECT
35+
36+
37+public:
38+ LauncherBackend(QObject *parent = 0);
39+ virtual ~LauncherBackend();
40+
41+ /**
42+ * @brief Returns a list of stored applications.
43+ * @returns A list of application IDs.
44+ */
45+ QStringList storedApplications() const;
46+
47+ /**
48+ * @brief Set the list of stored applications.
49+ *
50+ * Any previously stored information for apps not contained
51+ * in the list any more, e.g. the pinned state, will be
52+ * discarded.
53+ *
54+ * @param appIds The new list of stored applications.
55+ */
56+ void setStoredApplications(const QStringList &appIds);
57+
58+ /**
59+ * @brief Get the full path to the .desktop file.
60+ * @returns The full path to the .dekstop file.
61+ */
62+ QString desktopFile(const QString &appId) const;
63+
64+ /**
65+ * @brief Get the user friendly name of an application.
66+ * @param appId The ID of the application.
67+ * @returns The user friendly name of the application.
68+ */
69+ QString displayName(const QString &appId) const;
70+
71+ /**
72+ * @brief Get the icon of an application.
73+ * @param appId The ID of the application.
74+ * @returns The full path to the icon for the application.
75+ */
76+ QString icon(const QString &appId) const;
77+
78+ /**
79+ * @brief Is the app manually pinned?
80+ * @returns true if pinned, otherwise false.
81+ */
82+ bool isPinned(const QString &appId) const;
83+
84+ /**
85+ * @brief Change the pinned state of an application.
86+ * @param appId The application where the pinned flag should be set.
87+ * @param pinned true if pinned, otherwise false.
88+ */
89+ void setPinned(const QString &appId, bool pinned);
90+
91+ //TODO: Fill in getters for all the other things needed from the .desktop file.
92+
93+ /**
94+ * @brief Get the QuickList for an application.
95+ * @param appId The ID of the application.
96+ * @returns A QuickListModelInterface containing the QuickList.
97+ */
98+ QList<QuickListEntry> quickList(const QString &appId) const;
99+
100+ /**
101+ * @brief Execute an action from the quickList
102+ * @param appId The app ID for which the action was triggered
103+ * @param the quicklist ID of the action that was triggered
104+ */
105+ void triggerQuickListAction(const QString &appId, const QString &entryId);
106+
107+ /**
108+ * @brief Get the progress for the progress overlay of an application.
109+ * @param appId The ID of the application.
110+ * @returns The percentage of the overlay progress bar. -1 if no progress bar available.
111+ */
112+ int progress(const QString &appId) const;
113+
114+ /**
115+ * @brief Get the count of the count overlay of an application.
116+ * @param appId The ID of the application.
117+ * @returns The number to be displayed in the overlay. -1 if no count overlay is available.
118+ */
119+ int count(const QString &appId) const;
120+
121+Q_SIGNALS:
122+ void quickListChanged(const QString &appId, const QList<QuickListEntry> &quickList);
123+ void progressChanged(const QString &appId, int progress);
124+ void countChanged(const QString &appId, int count);
125+
126+private:
127+ QStringList m_storedApps;
128+ QHash<QString, QString> m_displayNameMap;
129+ QHash<QString, QString> m_iconMap;
130+};
131+
132+#endif // LAUNCHERBACKEND_H
plugins/Unity/categoryfilter.cpp → plugins/Unity/Launcher/common/quicklistentry.cpprenamed+28−19
@@ -1,8 +1,7 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
1+/* Copyright (C) 2013 Canonical, Ltd.
3 *
2 *
4 * Authors:
3 * Authors:
5− * Michał Sawicz <michal.sawicz@canonical.com>
4+ * Michael Zanetti <michael.zanetti@canonical.com>
6 *
5 *
7 * This program is free software; you can redistribute it and/or modify
6 * 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
7 * it under the terms of the GNU General Public License as published by
@@ -17,29 +16,39 @@
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
17 */
19
18
20−#include "categoryfilter.h"
19+#include "quicklistentry.h"
21
20
22−int const CATEGORY_COLUMN = 2;
21+QuickListEntry::QuickListEntry()
22+{
23+
24+}
25+
26+QString QuickListEntry::actionId() const
27+{
28+ return m_actionId;
29+}
30+
31+void QuickListEntry::setActionId(const QString &actionId)
32+{
33+ m_actionId = actionId;
34+}
35+
36+QString QuickListEntry::text() const
37+{
38+ return m_text;
39+}
23
40
24−CategoryFilter::CategoryFilter(QObject* parent)
41+void QuickListEntry::setText(const QString &text)
25− : QSortFilterProxyModelQML(parent)
26− , m_index(-1)
27{
42{
28− setDynamicSortFilter(true);
43+ m_text = text;
29− setFilterRole(CATEGORY_COLUMN);
30− setFilterRegExp(QString("^%1$").arg(m_index));
31}
44}
32
45
33−int CategoryFilter::index() const
46+QString QuickListEntry::icon() const
34{
47{
35− return m_index;
48+ return m_icon;
36}
49}
37
50
38−void CategoryFilter::setIndex(int index)
51+void QuickListEntry::setIcon(const QString &icon)
39{
52{
40− if (index != m_index) {
53+ m_icon = icon;
41− m_index = index;
42− setFilterRegExp(QString("^%1$").arg(m_index));
43− Q_EMIT indexChanged(m_index);
44− }
45}
54}
plugins/Unity/Launcher/common/quicklistentry.hnew file+44
@@ -0,0 +1,44 @@
1+/* Copyright (C) 2013 Canonical, Ltd.
2+ *
3+ * Authors:
4+ * Michael Zanetti <michael.zanetti@canonical.com>
5+ *
6+ * This program is free software; you can redistribute it and/or modify
7+ * it under the terms of the GNU General Public License as published by
8+ * the Free Software Foundation; version 3.
9+ *
10+ * This program is distributed in the hope that it will be useful,
11+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+ * GNU General Public License for more details.
14+ *
15+ * You should have received a copy of the GNU General Public License
16+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
17+ */
18+
19+#ifndef QUICKLISTENTRY_H
20+#define QUICKLISTENTRY_H
21+
22+#include <QString>
23+
24+class QuickListEntry
25+{
26+public:
27+ QuickListEntry();
28+
29+ QString actionId() const;
30+ void setActionId(const QString &actionId);
31+
32+ QString text() const;
33+ void setText(const QString &text);
34+
35+ QString icon() const;
36+ void setIcon(const QString &icon);
37+
38+private:
39+ QString m_actionId;
40+ QString m_text;
41+ QString m_icon;
42+};
43+
44+#endif // QUICKLISTENTRY
plugins/Unity/Launcher/launcheritem.cppnew file+127
@@ -0,0 +1,127 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Michael Zanetti <michael.zanetti@canonical.com>
18+ */
19+
20+#include "launcheritem.h"
21+#include "quicklistmodel.h"
22+
23+LauncherItem::LauncherItem(const QString &appId, const QString &desktopFile, const QString &name, const QString &icon, QObject *parent) :
24+ LauncherItemInterface(parent),
25+ m_appId(appId),
26+ m_desktopFile(desktopFile),
27+ m_name(name),
28+ m_icon(icon),
29+ m_pinned(false),
30+ m_running(false),
31+ m_recent(false),
32+ m_progress(-1),
33+ m_count(0),
34+ m_quickList(new QuickListModel(this))
35+{
36+
37+}
38+
39+QString LauncherItem::appId() const
40+{
41+ return m_appId;
42+}
43+
44+QString LauncherItem::desktopFile() const
45+{
46+ return m_desktopFile;
47+}
48+
49+QString LauncherItem::name() const
50+{
51+ return m_name;
52+}
53+
54+QString LauncherItem::icon() const
55+{
56+ return m_icon;
57+}
58+
59+bool LauncherItem::pinned() const
60+{
61+ return m_pinned;
62+}
63+
64+void LauncherItem::setPinned(bool pinned)
65+{
66+ if (m_pinned != pinned) {
67+ m_pinned = pinned;
68+ Q_EMIT pinnedChanged(pinned);
69+ }
70+}
71+
72+bool LauncherItem::running() const
73+{
74+ return m_running;
75+}
76+
77+void LauncherItem::setRunning(bool running)
78+{
79+ if (m_running != running) {
80+ m_running = running;
81+ Q_EMIT runningChanged(running);
82+ }
83+}
84+
85+bool LauncherItem::recent() const
86+{
87+ return m_recent;
88+}
89+
90+void LauncherItem::setRecent(bool recent)
91+{
92+ if (m_recent != recent) {
93+ m_recent = recent;
94+ Q_EMIT recentChanged(recent);
95+ }
96+}
97+
98+int LauncherItem::progress() const
99+{
100+ return m_progress;
101+}
102+
103+void LauncherItem::setProgress(int progress)
104+{
105+ if (m_progress != progress) {
106+ m_progress = progress;
107+ Q_EMIT progressChanged(progress);
108+ }
109+}
110+
111+int LauncherItem::count() const
112+{
113+ return m_count;
114+}
115+
116+void LauncherItem::setCount(int count)
117+{
118+ if (m_count != count) {
119+ m_count = count;
120+ Q_EMIT countChanged(count);
121+ }
122+}
123+
124+unity::shell::launcher::QuickListModelInterface *LauncherItem::quickList() const
125+{
126+ return m_quickList;
127+}
plugins/Unity/Launcher/launcheritem.hnew file+76
@@ -0,0 +1,76 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Michael Zanetti <michael.zanetti@canonical.com>
18+ */
19+
20+#ifndef LAUNCHERITEM_H
21+#define LAUNCHERITEM_H
22+
23+#include "quicklistmodel.h"
24+
25+#include <unity/shell/launcher/LauncherItemInterface.h>
26+
27+class QuickListModel;
28+
29+using namespace unity::shell::launcher;
30+
31+class LauncherItem: public LauncherItemInterface
32+{
33+ Q_OBJECT
34+public:
35+ LauncherItem(const QString &appId, const QString &desktopFile, const QString &name, const QString &icon, QObject *parent = 0);
36+
37+ QString appId() const;
38+ QString desktopFile() const;
39+ QString name() const;
40+ QString icon() const;
41+
42+ bool pinned() const;
43+ void setPinned(bool pinned);
44+
45+ bool running() const;
46+ void setRunning(bool running);
47+
48+ bool recent() const;
49+ void setRecent(bool recent);
50+
51+ int progress() const;
52+ void setProgress(int progress);
53+
54+ int count() const;
55+ void setCount(int count);
56+
57+ unity::shell::launcher::QuickListModelInterface *quickList() const;
58+
59+Q_SIGNALS:
60+ void favoriteChanged(bool favorite);
61+ void runningChanged(bool running);
62+
63+private:
64+ QString m_appId;
65+ QString m_desktopFile;
66+ QString m_name;
67+ QString m_icon;
68+ bool m_pinned;
69+ bool m_running;
70+ bool m_recent;
71+ int m_progress;
72+ int m_count;
73+ QuickListModel *m_quickList;
74+};
75+
76+#endif // LAUNCHERITEM_H
plugins/Unity/Launcher/launchermodel.cppnew file+170
@@ -0,0 +1,170 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Michael Zanetti <michael.zanetti@canonical.com>
18+ */
19+
20+#include "launchermodel.h"
21+#include "launcheritem.h"
22+#include "backend/launcherbackend.h"
23+
24+LauncherModel::LauncherModel(QObject *parent):
25+ LauncherModelInterface(parent),
26+ m_backend(new LauncherBackend(this))
27+{
28+ Q_FOREACH (const QString &entry, m_backend->storedApplications()) {
29+ LauncherItem *item = new LauncherItem(entry,
30+ m_backend->desktopFile(entry),
31+ m_backend->displayName(entry),
32+ m_backend->icon(entry),
33+ this);
34+ if (m_backend->isPinned(entry)) {
35+ item->setPinned(true);
36+ } else {
37+ item->setRecent(true);
38+ }
39+ m_list.append(item);
40+ }
41+}
42+
43+LauncherModel::~LauncherModel()
44+{
45+ while (!m_list.empty()) {
46+ m_list.takeFirst()->deleteLater();
47+ }
48+}
49+
50+int LauncherModel::rowCount(const QModelIndex &parent) const
51+{
52+ Q_UNUSED(parent)
53+ return m_list.count();
54+}
55+
56+QVariant LauncherModel::data(const QModelIndex &index, int role) const
57+{
58+ LauncherItem *item = m_list.at(index.row());
59+ switch(role) {
60+ case RoleAppId:
61+ return item->desktopFile();
62+ case RoleDesktopFile:
63+ return item->desktopFile();
64+ case RoleName:
65+ return item->name();
66+ case RoleIcon:
67+ return item->icon();
68+ case RolePinned:
69+ return item->pinned();
70+ }
71+
72+ return QVariant();
73+}
74+
75+unity::shell::launcher::LauncherItemInterface *LauncherModel::get(int index) const
76+{
77+ if (index < 0 || index >= m_list.count()) {
78+ return 0;
79+ }
80+ return m_list.at(index);
81+}
82+
83+void LauncherModel::move(int oldIndex, int newIndex)
84+{
85+ // Perform the move in our list
86+ beginMoveRows(QModelIndex(), oldIndex, oldIndex, QModelIndex(), newIndex);
87+ m_list.move(oldIndex, newIndex);
88+ endMoveRows();
89+
90+ storeAppList();
91+
92+ pin(m_list.at(newIndex)->appId());
93+}
94+
95+void LauncherModel::pin(const QString &appId, int index)
96+{
97+ int currentIndex = findApplication(appId);
98+
99+ if (currentIndex >= 0) {
100+ if (index == -1 || index == currentIndex) {
101+ m_list.at(currentIndex)->setPinned(true);
102+ QModelIndex modelIndex = this->index(currentIndex);
103+ Q_EMIT dataChanged(modelIndex, modelIndex);
104+ } else {
105+ move(currentIndex, index);
106+ }
107+ } else {
108+ if (index == -1) {
109+ index = m_list.count();
110+ }
111+ beginInsertRows(QModelIndex(), index, index);
112+ LauncherItem *item = new LauncherItem(appId,
113+ m_backend->desktopFile(appId),
114+ m_backend->displayName(appId),
115+ m_backend->icon(appId));
116+ item->setPinned(true);
117+ m_list.insert(index, item);
118+ endInsertRows();
119+ }
120+}
121+
122+void LauncherModel::requestRemove(const QString &appId)
123+{
124+ int index = findApplication(appId);
125+ if (index < 0) {
126+ return;
127+ }
128+
129+ beginRemoveRows(QModelIndex(), index, index);
130+ m_list.takeAt(index)->deleteLater();
131+ endRemoveRows();
132+
133+ storeAppList();
134+}
135+
136+void LauncherModel::quickListActionInvoked(const QString &appId, int actionIndex)
137+{
138+ int index = findApplication(appId);
139+ if (index < 0) {
140+ return;
141+ }
142+
143+ QuickListModel *model = qobject_cast<QuickListModel*>(m_list.at(index)->quickList());
144+ if (model) {
145+ QString actionId = model->get(actionIndex).actionId();
146+ m_backend->triggerQuickListAction(appId, actionId);
147+ }
148+}
149+
150+void LauncherModel::storeAppList()
151+{
152+ QStringList appIds;
153+ Q_FOREACH(LauncherItem *item, m_list) {
154+ if (item->pinned() || item->recent()) {
155+ appIds << item->appId();
156+ }
157+ }
158+ m_backend->setStoredApplications(appIds);
159+}
160+
161+int LauncherModel::findApplication(const QString &appId)
162+{
163+ for (int i = 0; i < m_list.count(); ++i) {
164+ LauncherItem *item = m_list.at(i);
165+ if (item->appId() == appId) {
166+ return i;
167+ }
168+ }
169+ return -1;
170+}
plugins/Unity/Launcher/launchermodel.hnew file+61
@@ -0,0 +1,61 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Michael Zanetti <michael.zanetti@canonical.com>
18+ */
19+
20+#ifndef LAUNCHERMODELH
21+#define LAUNCHERMODEL_H
22+
23+// unity-api
24+#include <unity/shell/launcher/LauncherModelInterface.h>
25+
26+// Qt
27+#include <QAbstractListModel>
28+
29+class LauncherItem;
30+class LauncherBackend;
31+
32+using namespace unity::shell::launcher;
33+
34+class LauncherModel: public LauncherModelInterface
35+{
36+ Q_OBJECT
37+
38+public:
39+ LauncherModel(QObject *parent = 0);
40+ ~LauncherModel();
41+
42+ int rowCount(const QModelIndex &parent) const;
43+
44+ QVariant data(const QModelIndex &index, int role) const;
45+
46+ Q_INVOKABLE unity::shell::launcher::LauncherItemInterface* get(int index) const;
47+ Q_INVOKABLE void move(int oldIndex, int newIndex);
48+ Q_INVOKABLE void pin(const QString &appId, int index = -1);
49+ Q_INVOKABLE void requestRemove(const QString &appId);
50+ Q_INVOKABLE void quickListActionInvoked(const QString &appId, int actionIndex);
51+
52+private:
53+ void storeAppList();
54+ int findApplication(const QString &appId);
55+
56+private:
57+ QList<LauncherItem*> m_list;
58+ LauncherBackend *m_backend;
59+};
60+
61+#endif // LAUNCHERMODEL_H
plugins/Unity/Launcher/plugin.cppnew file+47
@@ -0,0 +1,47 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Michael Zanetti <michael.zanetti@canonical.com>
18+ */
19+
20+// Qt
21+#include <QtQml>
22+
23+// self
24+#include "plugin.h"
25+
26+// local
27+#include "launchermodel.h"
28+#include "launcheritem.h"
29+
30+
31+using namespace unity::shell::launcher;
32+
33+static QObject* modelProvider(QQmlEngine* /* engine */, QJSEngine* /* scriptEngine */)
34+{
35+ return new LauncherModel();
36+}
37+
38+void UnityLauncherPlugin::registerTypes(const char *uri)
39+{
40+ Q_ASSERT(uri == QLatin1String("Unity.Launcher"));
41+
42+ qmlRegisterUncreatableType<LauncherModelInterface>(uri, 0, 1, "LauncherModelInterface", "Abstract Interface. Cannot be instantiated.");
43+ qmlRegisterUncreatableType<LauncherItemInterface>(uri, 0, 1, "LauncherItemInterface", "Abstract Interface. Cannot be instantiated.");
44+
45+ qmlRegisterSingletonType<LauncherModel>(uri, 0, 1, "LauncherModel", modelProvider);
46+ qmlRegisterUncreatableType<LauncherItem>(uri, 0, 1, "LauncherItem", "Can't create new Launcher Items in QML. Get them from the LauncherModel.");
47+}
plugins/Unity/categoryfilter.h → plugins/Unity/Launcher/plugin.hrenamed+10−24
@@ -1,9 +1,6 @@
1/*
1/*
2 * Copyright (C) 2013 Canonical, Ltd.
2 * Copyright (C) 2013 Canonical, Ltd.
3 *
3 *
4− * Authors:
5− * Michał Sawicz <michal.sawicz@canonical.com>
6− *
7 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 3.
6 * the Free Software Foundation; version 3.
@@ -15,34 +12,23 @@
15 *
12 *
16 * You should have received a copy of the GNU General Public License
13 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Author: Michael Zanetti <michael.zanetti@canonical.com>
18 */
17 */
19
18
20−#ifndef CATEGORY_FILTER_H
19+#ifndef UNITY_LAUNCHER_PLUGIN_H
21−#define CATEGORY_FILTER_H
20+#define UNITY_LAUNCHER_PLUGIN_H
22
21
23−// Utils
22+#include <QtQml/QQmlEngine>
24−#include "plugins/Utils/qsortfilterproxymodelqml.h"
23+#include <QtQml/QQmlExtensionPlugin>
25
24
26−class CategoryFilter : public QSortFilterProxyModelQML
25+class UnityLauncherPlugin : public QQmlExtensionPlugin
27{
26{
28 Q_OBJECT
27 Q_OBJECT
29−
28+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
30− Q_PROPERTY(int index READ index WRITE setIndex NOTIFY indexChanged)
31
29
32public:
30public:
33− explicit CategoryFilter(QObject* parent = 0);
31+ void registerTypes(const char *uri);
34−
35− /* getters */
36− int index() const;
37−
38− /* setters */
39− void setIndex(int index);
40−
41−Q_SIGNALS:
42− void indexChanged(int index);
43−
44−private:
45− int m_index;
46};
32};
47
33
48−#endif // CATEGORY_FILTER_H
34+#endif
plugins/Unity/Launcher/qmldirnew file+2
@@ -0,0 +1,2 @@
1+module Unity.Launcher
2+plugin UnityLauncher-qml
plugins/Unity/Launcher/quicklistmodel.cppnew file+60
@@ -0,0 +1,60 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Michael Zanetti <michael.zanetti@canonical.com>
18+ */
19+
20+#include "quicklistmodel.h"
21+
22+QuickListModel::QuickListModel(QObject *parent) :
23+ QuickListModelInterface(parent)
24+{
25+
26+}
27+
28+QuickListModel::~QuickListModel()
29+{
30+
31+}
32+
33+void QuickListModel::appendAction(const QuickListEntry &entry)
34+{
35+ beginInsertRows(QModelIndex(), m_list.count() - 1, m_list.count() -1);
36+ m_list.append(entry);
37+ endInsertRows();
38+}
39+
40+QuickListEntry QuickListModel::get(int index) const
41+{
42+ return m_list.at(index);
43+}
44+
45+int QuickListModel::rowCount(const QModelIndex &index) const
46+{
47+ Q_UNUSED(index)
48+ return m_list.count();
49+}
50+
51+QVariant QuickListModel::data(const QModelIndex &index, int role) const
52+{
53+ switch (role) {
54+ case RoleLabel:
55+ return m_list.at(index.row()).text();
56+ case RoleIcon:
57+ return m_list.at(index.row()).icon();
58+ }
59+ return QVariant();
60+}
plugins/Unity/Launcher/quicklistmodel.hnew file+48
@@ -0,0 +1,48 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Michael Zanetti <michael.zanetti@canonical.com>
18+ */
19+
20+#ifndef QUICKLISTMODEL_H
21+#define QUICKLISTMODEL_H
22+
23+#include "common/quicklistentry.h"
24+
25+#include <unity/shell/launcher/QuickListModelInterface.h>
26+
27+using namespace unity::shell::launcher;
28+
29+class QuickListModel: public QuickListModelInterface
30+{
31+ Q_OBJECT
32+
33+public:
34+ explicit QuickListModel(QObject *parent = 0);
35+
36+ ~QuickListModel();
37+
38+ void appendAction(const QuickListEntry &entry);
39+ QuickListEntry get(int index) const;
40+
41+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
42+ QVariant data(const QModelIndex &index, int role) const;
43+
44+private:
45+ QList<QuickListEntry> m_list;
46+};
47+
48+#endif // QUICKLISTMODEL_H
plugins/Unity/categories.cpp+56−42
@@ -3,6 +3,7 @@
3 *
3 *
4 * Authors:
4 * Authors:
5 * Michał Sawicz <michal.sawicz@canonical.com>
5 * Michał Sawicz <michal.sawicz@canonical.com>
6+ * Michal Hruby <michal.hruby@canonical.com>
6 *
7 *
7 * This program is free software; you can redistribute it and/or modify
8 * 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 * it under the terms of the GNU General Public License as published by
@@ -19,18 +20,25 @@
19
20
20// self
21// self
21#include "categories.h"
22#include "categories.h"
22−#include "categoryfilter.h"
23+#include "categoryresults.h"
24+
25+// TODO: use something from libunity once it's public
26+enum CategoryColumn {
27+ ID,
28+ DISPLAY_NAME,
29+ ICON_HINT,
30+ RENDERER_NAME,
31+ HINTS
32+};
23
33
24Categories::Categories(QObject* parent)
34Categories::Categories(QObject* parent)
25 : DeeListModel(parent)
35 : DeeListModel(parent)
26− , m_resultModel(0)
27{
36{
28− // FIXME: need to clean up unused filters on countChanged
29 m_roles[Categories::RoleId] = "id";
37 m_roles[Categories::RoleId] = "id";
30 m_roles[Categories::RoleName] = "name";
38 m_roles[Categories::RoleName] = "name";
31 m_roles[Categories::RoleIcon] = "icon";
39 m_roles[Categories::RoleIcon] = "icon";
32 m_roles[Categories::RoleRenderer] = "renderer";
40 m_roles[Categories::RoleRenderer] = "renderer";
33− m_roles[Categories::RoleContentType] = "content_type";
41+ m_roles[Categories::RoleContentType] = "contentType";
34 m_roles[Categories::RoleHints] = "hints";
42 m_roles[Categories::RoleHints] = "hints";
35 m_roles[Categories::RoleResults] = "results";
43 m_roles[Categories::RoleResults] = "results";
36 m_roles[Categories::RoleCount] = "count";
44 m_roles[Categories::RoleCount] = "count";
@@ -40,49 +48,57 @@ Categories::Categories(QObject* parent)
40 // change of the search term harder to reproduce
48 // change of the search term harder to reproduce
41 m_timer.setSingleShot(true);
49 m_timer.setSingleShot(true);
42 m_timer.setInterval(50);
50 m_timer.setInterval(50);
43− connect(&m_timer, SIGNAL(timeout()), this, SLOT(onEmitCountChanged()));
51+ connect(&m_timer, &QTimer::timeout, this, &Categories::onEmitCountChanged);
44}
52}
45
53
46−Categories::~Categories()
54+DeeListModel*
55+Categories::getResults(int index) const
47{
56{
48− qDeleteAll(m_filters);
57+ if (!m_results.contains(index)) {
49−}
58+ CategoryResults* results = new CategoryResults(const_cast<Categories*>(this));
59+ results->setCategoryIndex(index);
60+ connect(results, &DeeListModel::countChanged, this, &Categories::onCountChanged);
50
61
51−CategoryFilter*
62+ unsigned categoryIndex = static_cast<unsigned>(index);
52−Categories::getFilter(int index) const
63+ auto unity_results = m_unityScope->GetResultsForCategory(categoryIndex);
53−{
64+ results->setModel(unity_results->model());
54− if (!m_filters.contains(index)) {
55− CategoryFilter* filter = new CategoryFilter();
56− connect(filter, SIGNAL(countChanged()), this, SLOT(onCountChanged()));
57− filter->setModel(m_resultModel);
58− filter->setIndex(index);
59
65
60− m_filters.insert(index, filter);
66+ m_results.insert(index, results);
61 }
67 }
62
68
63− return m_filters[index];
69+ return m_results[index];
70+}
71+
72+void Categories::onCategoriesModelChanged(unity::glib::Object<DeeModel> model)
73+{
74+ m_updatedCategories.clear();
75+ // FIXME: this might destroy the renderer view and re-create it, optimize?
76+ Q_FOREACH(DeeListModel* model, m_results) {
77+ delete model;
78+ }
79+ m_results.clear();
80+ setModel(model);
64}
81}
65
82
66void
83void
67−Categories::setResultModel(DeeListModel* model)
84+Categories::setUnityScope(const unity::dash::Scope::Ptr& scope)
68{
85{
69− if (model != m_resultModel) {
86+ m_unityScope = scope;
70− m_resultModel = model;
71
87
72− Q_FOREACH(CategoryFilter* filter, m_filters) {
88+ // no need to call this, we'll get notified
73− filter->setModel(m_resultModel);
89+ //setModel(m_unityScope->categories()->model());
74− }
75
90
76− Q_EMIT resultModelChanged(m_resultModel);
91+ m_categoriesChangedConnection.disconnect();
77− }
92+ m_categoriesChangedConnection =
93+ m_unityScope->categories()->model.changed.connect(sigc::mem_fun(this, &Categories::onCategoriesModelChanged));
78}
94}
79
95
80void
96void
81Categories::onCountChanged()
97Categories::onCountChanged()
82{
98{
83− CategoryFilter* filter = qobject_cast<CategoryFilter*>(sender());
99+ CategoryResults* results = qobject_cast<CategoryResults*>(sender());
84− if (filter) {
100+ if (results) {
85− m_timerFilters << filter;
101+ m_updatedCategories << results->categoryIndex();
86 m_timer.start();
102 m_timer.start();
87 }
103 }
88}
104}
@@ -92,11 +108,12 @@ Categories::onEmitCountChanged()
92{
108{
93 QVector<int> roles;
109 QVector<int> roles;
94 roles.append(Categories::RoleCount);
110 roles.append(Categories::RoleCount);
95− Q_FOREACH(CategoryFilter* filter, m_timerFilters) {
111+ Q_FOREACH(int categoryIndex, m_updatedCategories) {
112+ if (!m_results.contains(categoryIndex)) continue;
96− QModelIndex changedIndex = index(filter->index());
113+ QModelIndex changedIndex = index(categoryIndex);
97 Q_EMIT dataChanged(changedIndex, changedIndex, roles);
114 Q_EMIT dataChanged(changedIndex, changedIndex, roles);
98 }
115 }
99− m_timerFilters.clear();
116+ m_updatedCategories.clear();
100}
117}
101
118
102QHash<int, QByteArray>
119QHash<int, QByteArray>
@@ -116,25 +133,22 @@ Categories::data(const QModelIndex& index, int role) const
116 case RoleId:
133 case RoleId:
117 return QVariant::fromValue(index.row());
134 return QVariant::fromValue(index.row());
118 case RoleName:
135 case RoleName:
119− return QVariant::fromValue(DeeListModel::data(index, 1)); //DISPLAY_NAME
136+ return DeeListModel::data(index, CategoryColumn::DISPLAY_NAME);
120 case RoleIcon:
137 case RoleIcon:
121− return QVariant::fromValue(DeeListModel::data(index, 2)); //ICON_HINT
138+ return DeeListModel::data(index, CategoryColumn::ICON_HINT);
122 case RoleRenderer:
139 case RoleRenderer:
123− return QVariant::fromValue(DeeListModel::data(index, 3)); //RENDERER_NAME
140+ return DeeListModel::data(index, CategoryColumn::RENDERER_NAME);
124 case RoleContentType:
141 case RoleContentType:
125 {
142 {
126− auto hints = QVariant::fromValue(DeeListModel::data(index, 4)).toHash();
143+ auto hints = DeeListModel::data(index, CategoryColumn::HINTS).toHash();
127 return hints.contains("content-type") ? hints["content-type"] : QVariant(QString("default"));
144 return hints.contains("content-type") ? hints["content-type"] : QVariant(QString("default"));
128 }
145 }
129 case RoleHints:
146 case RoleHints:
130− return QVariant::fromValue(DeeListModel::data(index, 4)); //HINTS
147+ return DeeListModel::data(index, CategoryColumn::HINTS);
131 case RoleResults:
148 case RoleResults:
132− return QVariant::fromValue(getFilter(index.row()));
149+ return QVariant::fromValue(getResults(index.row()));
133 case RoleCount:
150 case RoleCount:
134− {
135− CategoryFilter* filter = getFilter(index.row());
136− return QVariant::fromValue(filter->rowCount());
151+ return QVariant::fromValue(getResults(index.row())->rowCount());
137− }
138 default:
152 default:
139 return QVariant();
153 return QVariant();
140 }
154 }
plugins/Unity/categories.h+13−16
@@ -3,6 +3,7 @@
3 *
3 *
4 * Authors:
4 * Authors:
5 * Michał Sawicz <michal.sawicz@canonical.com>
5 * Michał Sawicz <michal.sawicz@canonical.com>
6+ * Michal Hruby <michal.hruby@canonical.com>
6 *
7 *
7 * This program is free software; you can redistribute it and/or modify
8 * 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 * it under the terms of the GNU General Public License as published by
@@ -21,25 +22,24 @@
21#ifndef CATEGORIES_H
22#ifndef CATEGORIES_H
22#define CATEGORIES_H
23#define CATEGORIES_H
23
24
25+// unity-core
26+#include <UnityCore/Scope.h>
27+
24// dee-qt
28// dee-qt
25#include "deelistmodel.h"
29#include "deelistmodel.h"
26
30
31+#include <QPointer>
27#include <QSet>
32#include <QSet>
28#include <QTimer>
33#include <QTimer>
29
34
30−class CategoryFilter;
31−
32class Categories : public DeeListModel
35class Categories : public DeeListModel
33{
36{
34 Q_OBJECT
37 Q_OBJECT
35
38
36 Q_ENUMS(Roles)
39 Q_ENUMS(Roles)
37
40
38− Q_PROPERTY(DeeListModel* resultModel READ resultModel WRITE setResultModel NOTIFY resultModelChanged)
39−
40public:
41public:
41 explicit Categories(QObject* parent = 0);
42 explicit Categories(QObject* parent = 0);
42− ~Categories();
43
43
44 enum Roles {
44 enum Roles {
45 RoleId,
45 RoleId,
@@ -56,27 +56,24 @@ public:
56
56
57 QHash<int, QByteArray> roleNames() const;
57 QHash<int, QByteArray> roleNames() const;
58
58
59− /* getters */
60− DeeListModel* resultModel() { return m_resultModel; }
61−
62 /* setters */
59 /* setters */
63− void setResultModel(DeeListModel*);
60+ void setUnityScope(const unity::dash::Scope::Ptr& scope);
64−
65−Q_SIGNALS:
66− void resultModelChanged(DeeListModel*);
67
61
68private Q_SLOTS:
62private Q_SLOTS:
69 void onCountChanged();
63 void onCountChanged();
70 void onEmitCountChanged();
64 void onEmitCountChanged();
71
65
72private:
66private:
73− CategoryFilter* getFilter(int index) const;
67+ void onCategoriesModelChanged(unity::glib::Object<DeeModel> model);
68+
69+ DeeListModel* getResults(int index) const;
74
70
71+ unity::dash::Scope::Ptr m_unityScope;
75 QTimer m_timer;
72 QTimer m_timer;
76− QSet<CategoryFilter*> m_timerFilters;
73+ QSet<int> m_updatedCategories;
77 QHash<int, QByteArray> m_roles;
74 QHash<int, QByteArray> m_roles;
78− DeeListModel* m_resultModel;
75+ mutable QMap<int, DeeListModel*> m_results;
79− mutable QMap<int, CategoryFilter*> m_filters;
76+ sigc::connection m_categoriesChangedConnection;
80};
77};
81
78
82#endif // CATEGORIES_H
79#endif // CATEGORIES_H
plugins/Unity/categoryresults.cppnew file+96
@@ -0,0 +1,96 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Michal Hruby <michal.hruby@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 "categoryresults.h"
22+
23+// TODO: use something from libunity once it's public
24+enum ResultsColumn {
25+ URI,
26+ ICON_HINT,
27+ CATEGORY,
28+ RESULT_TYPE,
29+ MIMETYPE,
30+ TITLE,
31+ COMMENT,
32+ DND_URI,
33+ METADATA
34+};
35+
36+CategoryResults::CategoryResults(QObject* parent)
37+ : DeeListModel(parent)
38+ , m_categoryIndex(-1)
39+{
40+ m_roles[CategoryResults::RoleUri] = "uri";
41+ m_roles[CategoryResults::RoleIconHint] = "icon";
42+ m_roles[CategoryResults::RoleCategory] = "category";
43+ m_roles[CategoryResults::RoleMimetype] = "mimetype";
44+ m_roles[CategoryResults::RoleTitle] = "title";
45+ m_roles[CategoryResults::RoleComment] = "comment";
46+ m_roles[CategoryResults::RoleDndUri] = "dndUri";
47+ m_roles[CategoryResults::RoleMetadata] = "metadata";
48+}
49+
50+int CategoryResults::categoryIndex() const
51+{
52+ return m_categoryIndex;
53+}
54+
55+void CategoryResults::setCategoryIndex(int index)
56+{
57+ if (m_categoryIndex != index) {
58+ m_categoryIndex = index;
59+ Q_EMIT categoryIndexChanged(m_categoryIndex);
60+ }
61+}
62+
63+QHash<int, QByteArray>
64+CategoryResults::roleNames() const
65+{
66+ return m_roles;
67+}
68+
69+QVariant
70+CategoryResults::data(const QModelIndex& index, int role) const
71+{
72+ if (!index.isValid()) {
73+ return QVariant();
74+ }
75+
76+ switch (role) {
77+ case RoleUri:
78+ return DeeListModel::data(index, ResultsColumn::URI);
79+ case RoleIconHint:
80+ return DeeListModel::data(index, ResultsColumn::ICON_HINT);
81+ case RoleCategory:
82+ return DeeListModel::data(index, ResultsColumn::CATEGORY);
83+ case RoleMimetype:
84+ return DeeListModel::data(index, ResultsColumn::MIMETYPE);
85+ case RoleTitle:
86+ return DeeListModel::data(index, ResultsColumn::TITLE);
87+ case RoleComment:
88+ return DeeListModel::data(index, ResultsColumn::COMMENT);
89+ case RoleDndUri:
90+ return DeeListModel::data(index, ResultsColumn::DND_URI);
91+ case RoleMetadata:
92+ return DeeListModel::data(index, ResultsColumn::METADATA);
93+ default:
94+ return QVariant();
95+ }
96+}
plugins/Unity/categoryresults.hnew file+67
@@ -0,0 +1,67 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Michal Hruby <michal.hruby@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+
21+#ifndef CATEGORY_RESULTS_H
22+#define CATEGORY_RESULTS_H
23+
24+// dee-qt
25+#include "deelistmodel.h"
26+
27+class CategoryResults : public DeeListModel
28+{
29+ Q_OBJECT
30+
31+ Q_ENUMS(Roles)
32+
33+ Q_PROPERTY(int categoryIndex READ categoryIndex WRITE setCategoryIndex NOTIFY categoryIndexChanged)
34+
35+public:
36+ explicit CategoryResults(QObject* parent = 0);
37+
38+ enum Roles {
39+ RoleUri,
40+ RoleIconHint,
41+ RoleCategory,
42+ RoleMimetype,
43+ RoleTitle,
44+ RoleComment,
45+ RoleDndUri,
46+ RoleMetadata
47+ };
48+
49+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
50+
51+ QHash<int, QByteArray> roleNames() const;
52+
53+ /* getters */
54+ int categoryIndex() const;
55+
56+ /* setters */
57+ void setCategoryIndex(int index);
58+
59+Q_SIGNALS:
60+ void categoryIndexChanged(int index);
61+
62+private:
63+ QHash<int, QByteArray> m_roles;
64+ int m_categoryIndex;
65+};
66+
67+#endif // CATEGORY_RESULTS_H
plugins/Unity/genericpreview.cpp+5
@@ -24,3 +24,8 @@ GenericPreview::GenericPreview(QObject *parent):
24 Preview(parent)
24 Preview(parent)
25{
25{
26}
26}
27+
28+void GenericPreview::setUnityPreview(unity::dash::Preview::Ptr /* unityPreview */)
29+{
30+ Q_EMIT previewChanged();
31+}
plugins/Unity/genericpreview.h+6
@@ -33,6 +33,12 @@ class GenericPreview : public Preview
33
33
34public:
34public:
35 explicit GenericPreview(QObject *parent = 0);
35 explicit GenericPreview(QObject *parent = 0);
36+
37+Q_SIGNALS:
38+ void previewChanged();
39+
40+protected:
41+ void setUnityPreview(unity::dash::Preview::Ptr unityPreview) override;
36};
42};
37
43
38Q_DECLARE_METATYPE(GenericPreview *)
44Q_DECLARE_METATYPE(GenericPreview *)
plugins/Unity/launchermodel.cppdeleted−153
@@ -1,153 +0,0 @@
1−/*
2− * Copyright (C) 2011 Canonical, Ltd.
3− *
4− * Authors:
5− * Michael Zanetti <michael.zanetti@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 "launchermodel.h"
21−
22−LauncherModel::LauncherModel(QObject *parent): QAbstractListModel(parent)
23−{
24− // FIXME: Dummy data... Aggregate real data from backends
25−
26− // Fake favorites
27− LauncherItem *item = new LauncherItem("/usr/share/applications/phone-app.desktop", "Phone", "phone-app");
28− m_list.append(item);
29− item = new LauncherItem("/usr/share/applications/camera-app.desktop", "Camera", "camera");
30− m_list.append(item);
31− item = new LauncherItem("/usr/share/applications/gallery-app.desktop", "Gallery", "gallery");
32− m_list.append(item);
33− item = new LauncherItem("/usr/share/applications/facebook-webapp.desktop", "Facebook", "facebook");
34− m_list.append(item);
35− item = new LauncherItem("/usr/share/applications/webbrowser-app.desktop", "Browser", "browser");
36− m_list.append(item);
37− item = new LauncherItem("/usr/share/applications/twitter-webapp.desktop", "Twitter", "twitter");
38− m_list.append(item);
39− item = new LauncherItem("/usr/share/applications/gmail-webapp.desktop", "GMail", "gmail");
40− m_list.append(item);
41− item = new LauncherItem("/usr/share/applications/ubuntu-weather-app.desktop", "Weather", "weather");
42− m_list.append(item);
43− item = new LauncherItem("/usr/share/applications/notes-app.desktop", "Notepad", "notepad");
44− m_list.append(item);
45− item = new LauncherItem("/usr/share/applications/ubuntu-calendar-app.desktop","Calendar", "calendar");
46− m_list.append(item);
47−}
48−
49−LauncherModel::~LauncherModel()
50−{
51− while (!m_list.empty()) {
52− m_list.takeFirst()->deleteLater();
53− }
54−}
55−
56−int LauncherModel::rowCount(const QModelIndex &parent) const
57−{
58− Q_UNUSED(parent)
59− return m_list.count();
60−}
61−
62−QVariant LauncherModel::data(const QModelIndex &index, int role) const
63−{
64− LauncherItem *item = m_list.at(index.row());
65− switch(role) {
66− case RoleName:
67− return item->name();
68− case RoleIcon:
69− return item->icon();
70− case RoleFavorite:
71− return item->favorite();
72− }
73−
74− return QVariant();
75−}
76−
77−LauncherItem *LauncherModel::get(int index) const
78−{
79− if (index < 0 || index >= m_list.count()) {
80− return 0;
81− }
82− return m_list.at(index);
83−}
84−
85−void LauncherModel::move(int oldIndex, int newIndex)
86−{
87− beginMoveRows(QModelIndex(), oldIndex, oldIndex, QModelIndex(), newIndex);
88− m_list.move(oldIndex, newIndex);
89− endMoveRows();
90−}
91−
92−QHash<int, QByteArray> LauncherModel::roleNames() const
93−{
94− QHash<int, QByteArray> roles;
95− roles.insert(RoleDesktopFile, "desktopFile");
96− roles.insert(RoleName, "name");
97− roles.insert(RoleIcon, "icon");
98− roles.insert(RoleFavorite, "favorite");
99− roles.insert(RoleRunning, "runnng");
100− return roles;
101−}
102−
103−
104−LauncherItem::LauncherItem(const QString &desktopFile, const QString &name, const QString &icon, QObject *parent):
105− QObject(parent),
106− m_desktopFile(desktopFile),
107− m_name(name),
108− m_icon(icon),
109− m_favorite(false)
110−{
111−
112−}
113−
114−QString LauncherItem::desktopFile() const
115−{
116− return m_desktopFile;
117−}
118−
119−QString LauncherItem::name() const
120−{
121− return m_name;
122−}
123−
124−QString LauncherItem::icon() const
125−{
126− return m_icon;
127−}
128−
129−bool LauncherItem::favorite() const
130−{
131− return m_favorite;
132−}
133−
134−void LauncherItem::setFavorite(bool favorite)
135−{
136− if (m_favorite != favorite) {
137− m_favorite = favorite;
138− Q_EMIT favoriteChanged(m_favorite);
139− }
140−}
141−
142−bool LauncherItem::running() const
143−{
144− return m_running;
145−}
146−
147−void LauncherItem::setRunning(bool running)
148−{
149− if (m_running != running) {
150− m_running = running;
151− Q_EMIT runningChanged(running);
152− }
153−}
plugins/Unity/launchermodel.hdeleted−86
@@ -1,86 +0,0 @@
1−/*
2− * Copyright (C) 2011 Canonical, Ltd.
3− *
4− * Authors:
5− * Michael Zanetti <michael.zanetti@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 <QAbstractListModel>
21−
22−class LauncherItem;
23−
24−class LauncherModel: public QAbstractListModel
25−{
26− Q_OBJECT
27−
28−public:
29− enum Roles {
30− RoleDesktopFile = Qt::UserRole,
31− RoleName,
32− RoleIcon,
33− RoleFavorite,
34− RoleRunning
35− };
36−
37− LauncherModel(QObject *parent = 0);
38− ~LauncherModel();
39−
40− int rowCount(const QModelIndex &parent) const;
41−
42− QVariant data(const QModelIndex &index, int role) const;
43−
44− Q_INVOKABLE LauncherItem* get(int index) const;
45− Q_INVOKABLE void move(int oldIndex, int newIndex);
46−
47− QHash<int, QByteArray> roleNames() const;
48−
49−private:
50− QList<LauncherItem*> m_list;
51−};
52−
53−class LauncherItem: public QObject
54−{
55− Q_OBJECT
56− Q_PROPERTY(QString desktopFile READ desktopFile CONSTANT)
57− Q_PROPERTY(QString name READ name CONSTANT)
58− Q_PROPERTY(QString icon READ icon CONSTANT)
59− Q_PROPERTY(bool favorite READ favorite WRITE setFavorite NOTIFY favoriteChanged)
60− Q_PROPERTY(bool running READ running WRITE setRunning NOTIFY runningChanged)
61−
62−public:
63− LauncherItem(const QString &desktopFile, const QString &name, const QString &icon, QObject *parent = 0);
64−
65− QString desktopFile() const;
66−
67− QString name() const;
68− QString icon() const;
69−
70− bool favorite() const;
71− void setFavorite(bool favorite);
72−
73− bool running() const;
74− void setRunning(bool running);
75−
76−Q_SIGNALS:
77− void favoriteChanged(bool favorite);
78− void runningChanged(bool running);
79−
80−private:
81− QString m_desktopFile;
82− QString m_name;
83− QString m_icon;
84− bool m_favorite;
85− bool m_running;
86−};
plugins/Unity/plugin.cpp+4−5
@@ -27,12 +27,12 @@
27#include "preview.h"
27#include "preview.h"
28#include "previewaction.h"
28#include "previewaction.h"
29#include "previewinfohint.h"
29#include "previewinfohint.h"
30+#include "socialpreviewcomment.h"
30#include "scope.h"
31#include "scope.h"
31#include "scopes.h"
32#include "scopes.h"
32#include "categories.h"
33#include "categories.h"
33−#include "categoryfilter.h"
34+#include "categoryresults.h"
34#include "bottombarvisibilitycommunicatorshell.h"
35#include "bottombarvisibilitycommunicatorshell.h"
35−#include "launchermodel.h"
36
36
37// libqtdee
37// libqtdee
38#include "deelistmodel.h"
38#include "deelistmodel.h"
@@ -46,13 +46,12 @@ void UnityPlugin::registerTypes(const char *uri)
46 qmlRegisterUncreatableType<Preview>(uri, 0, 1, "Preview", "Can't create Preview object in QML.");
46 qmlRegisterUncreatableType<Preview>(uri, 0, 1, "Preview", "Can't create Preview object in QML.");
47 qmlRegisterUncreatableType<PreviewAction>(uri, 0, 1, "PreviewAction", "Can't create PreviewAction object in QML.");
47 qmlRegisterUncreatableType<PreviewAction>(uri, 0, 1, "PreviewAction", "Can't create PreviewAction object in QML.");
48 qmlRegisterUncreatableType<PreviewInfoHint>(uri, 0, 1, "PreviewInfoHint", "Can't create PreviewInfoHint object in QML.");
48 qmlRegisterUncreatableType<PreviewInfoHint>(uri, 0, 1, "PreviewInfoHint", "Can't create PreviewInfoHint object in QML.");
49+ qmlRegisterUncreatableType<SocialPreviewComment>(uri, 0, 1, "SocialPreviewComment", "Can't create SocialPreviewComment object in QML.");
49 qmlRegisterType<Scope>(uri, 0, 1, "Scope");
50 qmlRegisterType<Scope>(uri, 0, 1, "Scope");
50 qmlRegisterType<Scopes>(uri, 0, 1, "Scopes");
51 qmlRegisterType<Scopes>(uri, 0, 1, "Scopes");
51 qmlRegisterType<Categories>(uri, 0, 1, "Categories");
52 qmlRegisterType<Categories>(uri, 0, 1, "Categories");
52− qmlRegisterType<CategoryFilter>(uri, 0, 1, "CategoryFilter");
53+ qmlRegisterUncreatableType<CategoryResults>(uri, 0, 1, "CategoryResults", "Can't create new Category Results in QML. Get them from Categories instance.");
53 qmlRegisterType<DeeListModel>(uri, 0, 1, "DeeListModel");
54 qmlRegisterType<DeeListModel>(uri, 0, 1, "DeeListModel");
54− qmlRegisterType<LauncherModel>(uri, 0, 1, "LauncherModel");
55− qmlRegisterUncreatableType<LauncherItem>(uri, 0, 1, "LauncherItem", "Can't create new Launcher Items in QML. Get them from the LauncherModel.");
56 qmlRegisterUncreatableType<BottomBarVisibilityCommunicatorShell>(uri, 0, 1, "BottomBarVisibilityCommunicatorShell", "Can't create BottomBarVisibilityCommunicatorShell");
55 qmlRegisterUncreatableType<BottomBarVisibilityCommunicatorShell>(uri, 0, 1, "BottomBarVisibilityCommunicatorShell", "Can't create BottomBarVisibilityCommunicatorShell");
57}
56}
58
57
plugins/Unity/preview.cpp+4
@@ -25,6 +25,7 @@
25#include "applicationpreview.h"
25#include "applicationpreview.h"
26#include "moviepreview.h"
26#include "moviepreview.h"
27#include "musicpreview.h"
27#include "musicpreview.h"
28+#include "socialpreview.h"
28#include "variantutils.h"
29#include "variantutils.h"
29
30
30// Qt
31// Qt
@@ -35,6 +36,7 @@
35#include <UnityCore/ApplicationPreview.h>
36#include <UnityCore/ApplicationPreview.h>
36#include <UnityCore/MoviePreview.h>
37#include <UnityCore/MoviePreview.h>
37#include <UnityCore/MusicPreview.h>
38#include <UnityCore/MusicPreview.h>
39+#include <UnityCore/SocialPreview.h>
38
40
39Preview::Preview(QObject *parent):
41Preview::Preview(QObject *parent):
40 QObject(parent),
42 QObject(parent),
@@ -124,6 +126,8 @@ Preview* Preview::newFromUnityPreview(unity::dash::Preview::Ptr unityPreview)
124 preview = new MoviePreview();
126 preview = new MoviePreview();
125 } else if (dynamic_cast<unity::dash::ApplicationPreview *>(unityPreview.get()) != nullptr) {
127 } else if (dynamic_cast<unity::dash::ApplicationPreview *>(unityPreview.get()) != nullptr) {
126 preview = new ApplicationPreview();
128 preview = new ApplicationPreview();
129+ } else if (dynamic_cast<unity::dash::SocialPreview *>(unityPreview.get()) != nullptr) {
130+ preview = new SocialPreview();
127 } else {
131 } else {
128 qWarning() << "Unknown preview type: " << typeid(*unityPreview).name();
132 qWarning() << "Unknown preview type: " << typeid(*unityPreview).name();
129 preview = new GenericPreview();
133 preview = new GenericPreview();
plugins/Unity/previewaction.h+1−1
@@ -36,7 +36,7 @@ enum LayoutHint // keep in sync with unty::dash::LayoutHint
36 Bottom
36 Bottom
37};
37};
38
38
39−class PreviewAction : public QObject
39+class Q_DECL_EXPORT PreviewAction : public QObject
40{
40{
41 Q_OBJECT
41 Q_OBJECT
42
42
plugins/Unity/qmldir+1
@@ -1,2 +1,3 @@
1module Unity
1module Unity
2plugin Unity-qml
2plugin Unity-qml
3+typeinfo plugin.qmltypes
plugins/Unity/scope.cpp+19−57
@@ -3,6 +3,7 @@
3 *
3 *
4 * Authors:
4 * Authors:
5 * Florian Boucault <florian.boucault@canonical.com>
5 * Florian Boucault <florian.boucault@canonical.com>
6+ * Michal Hruby <michal.hruby@canonical.com>
6 *
7 *
7 * This program is free software; you can redistribute it and/or modify
8 * 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 * it under the terms of the GNU General Public License as published by
@@ -38,10 +39,7 @@
38Scope::Scope(QObject *parent) :
39Scope::Scope(QObject *parent) :
39 QObject(parent)
40 QObject(parent)
40{
41{
41− m_results = new DeeListModel(this);
42− m_categories = new Categories(this);
42+ m_categories.reset(new Categories(this));
43−
44− m_categories->setResultModel(m_results);
45}
43}
46
44
47QString Scope::id() const
45QString Scope::id() const
@@ -84,14 +82,9 @@ bool Scope::connected() const
84 return m_unityScope->connected();
82 return m_unityScope->connected();
85}
83}
86
84
87−DeeListModel* Scope::results() const
88−{
89− return m_results;
90−}
91−
92Categories* Scope::categories() const
85Categories* Scope::categories() const
93{
86{
94− return m_categories;
87+ return m_categories.get();
95}
88}
96
89
97QString Scope::searchQuery() const
90QString Scope::searchQuery() const
@@ -104,6 +97,11 @@ QString Scope::noResultsHint() const
104 return m_noResultsHint;
97 return m_noResultsHint;
105}
98}
106
99
100+QString Scope::formFactor() const
101+{
102+ return m_formFactor;
103+}
104+
107void Scope::setSearchQuery(const QString& search_query)
105void Scope::setSearchQuery(const QString& search_query)
108{
106{
109 /* Checking for m_searchQuery.isNull() which returns true only when the string
107 /* Checking for m_searchQuery.isNull() which returns true only when the string
@@ -125,6 +123,15 @@ void Scope::setNoResultsHint(const QString& hint) {
125 }
123 }
126}
124}
127
125
126+void Scope::setFormFactor(const QString& form_factor) {
127+ if (form_factor != m_formFactor) {
128+ m_formFactor = form_factor;
129+ if (m_unityScope) {
130+ m_unityScope->form_factor = m_formFactor.toStdString();
131+ }
132+ Q_EMIT formFactorChanged();
133+ }
134+}
128
135
129unity::dash::LocalResult Scope::createLocalResult(const QVariant &uri, const QVariant &icon_hint,
136unity::dash::LocalResult Scope::createLocalResult(const QVariant &uri, const QVariant &icon_hint,
130 const QVariant &category, const QVariant &result_type,
137 const QVariant &category, const QVariant &result_type,
@@ -237,18 +244,9 @@ void Scope::setUnityScope(const unity::dash::Scope::Ptr& scope)
237{
244{
238 m_unityScope = scope;
245 m_unityScope = scope;
239
246
240− if (QString::fromStdString(m_unityScope->results()->swarm_name) == QString(":local")) {
247+ m_categories->setUnityScope(m_unityScope);
241− m_results->setModel(m_unityScope->results()->model());
242− } else {
243− m_results->setName(QString::fromStdString(m_unityScope->results()->swarm_name));
244− }
245−
246− if (QString::fromStdString(m_unityScope->categories()->swarm_name) == QString(":local")) {
247− m_categories->setModel(m_unityScope->categories()->model());
248− } else {
249− m_categories->setName(QString::fromStdString(m_unityScope->categories()->swarm_name));
250− }
251
248
249+ m_unityScope->form_factor = m_formFactor.toStdString();
252 /* Property change signals */
250 /* Property change signals */
253 m_unityScope->id.changed.connect(sigc::mem_fun(this, &Scope::idChanged));
251 m_unityScope->id.changed.connect(sigc::mem_fun(this, &Scope::idChanged));
254 m_unityScope->name.changed.connect(sigc::mem_fun(this, &Scope::nameChanged));
252 m_unityScope->name.changed.connect(sigc::mem_fun(this, &Scope::nameChanged));
@@ -258,12 +256,6 @@ void Scope::setUnityScope(const unity::dash::Scope::Ptr& scope)
258 m_unityScope->visible.changed.connect(sigc::mem_fun(this, &Scope::visibleChanged));
256 m_unityScope->visible.changed.connect(sigc::mem_fun(this, &Scope::visibleChanged));
259 m_unityScope->shortcut.changed.connect(sigc::mem_fun(this, &Scope::shortcutChanged));
257 m_unityScope->shortcut.changed.connect(sigc::mem_fun(this, &Scope::shortcutChanged));
260 m_unityScope->connected.changed.connect(sigc::mem_fun(this, &Scope::connectedChanged));
258 m_unityScope->connected.changed.connect(sigc::mem_fun(this, &Scope::connectedChanged));
261− m_unityScope->results.changed.connect(sigc::mem_fun(this, &Scope::onResultsChanged));
262− m_unityScope->results()->swarm_name.changed.connect(sigc::mem_fun(this, &Scope::onResultsSwarmNameChanged));
263− m_unityScope->results()->model.changed.connect(sigc::mem_fun(this, &Scope::onResultsModelChanged));
264− m_unityScope->categories()->model.changed.connect(sigc::mem_fun(this, &Scope::onCategoriesModelChanged));
265− m_unityScope->categories.changed.connect(sigc::mem_fun(this, &Scope::onCategoriesChanged));
266− m_unityScope->categories()->swarm_name.changed.connect(sigc::mem_fun(this, &Scope::onCategoriesSwarmNameChanged));
267 /* Signals forwarding */
259 /* Signals forwarding */
268 connect(this, SIGNAL(searchFinished(const std::string &, unity::glib::HintsMap const &, unity::glib::Error const &)), SLOT(onSearchFinished(const std::string &, unity::glib::HintsMap const &)));
260 connect(this, SIGNAL(searchFinished(const std::string &, unity::glib::HintsMap const &, unity::glib::Error const &)), SLOT(onSearchFinished(const std::string &, unity::glib::HintsMap const &)));
269
261
@@ -294,36 +286,6 @@ void Scope::synchronizeStates()
294 }
286 }
295}
287}
296
288
297−void Scope::onResultsSwarmNameChanged(const std::string& /* swarm_name */)
298−{
299− m_results->setName(QString::fromStdString(m_unityScope->results()->swarm_name));
300−}
301−
302−void Scope::onResultsChanged(const unity::dash::Results::Ptr& /* results */)
303−{
304− m_results->setName(QString::fromStdString(m_unityScope->results()->swarm_name));
305−}
306−
307−void Scope::onResultsModelChanged(unity::glib::Object<DeeModel> /* model */)
308−{
309− m_results->setModel(m_unityScope->results()->model());
310−}
311−
312−void Scope::onCategoriesSwarmNameChanged(const std::string& /* swarm_name */)
313−{
314− m_categories->setName(QString::fromStdString(m_unityScope->categories()->swarm_name));
315−}
316−
317−void Scope::onCategoriesChanged(const unity::dash::Categories::Ptr& /* categories */)
318−{
319− m_categories->setName(QString::fromStdString(m_unityScope->categories()->swarm_name));
320−}
321−
322−void Scope::onCategoriesModelChanged(unity::glib::Object<DeeModel> model)
323−{
324− m_categories->setModel(model);
325−}
326−
327void Scope::onSearchFinished(const std::string& /* query */, unity::glib::HintsMap const &hints)
289void Scope::onSearchFinished(const std::string& /* query */, unity::glib::HintsMap const &hints)
328{
290{
329 QString hint;
291 QString hint;
plugins/Unity/scope.h+8−12
@@ -32,7 +32,8 @@
32// dee-qt
32// dee-qt
33#include "deelistmodel.h"
33#include "deelistmodel.h"
34
34
35−class Categories;
35+#include "categories.h"
36+
36class Preview;
37class Preview;
37
38
38class Scope : public QObject
39class Scope : public QObject
@@ -47,11 +48,11 @@ class Scope : public QObject
47 Q_PROPERTY(bool visible READ visible NOTIFY visibleChanged)
48 Q_PROPERTY(bool visible READ visible NOTIFY visibleChanged)
48 Q_PROPERTY(QString shortcut READ shortcut NOTIFY shortcutChanged)
49 Q_PROPERTY(QString shortcut READ shortcut NOTIFY shortcutChanged)
49 Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged)
50 Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged)
50− Q_PROPERTY(DeeListModel* results READ results NOTIFY resultsChanged)
51 Q_PROPERTY(Categories* categories READ categories NOTIFY categoriesChanged)
51 Q_PROPERTY(Categories* categories READ categories NOTIFY categoriesChanged)
52
52
53 Q_PROPERTY(QString searchQuery READ searchQuery WRITE setSearchQuery NOTIFY searchQueryChanged)
53 Q_PROPERTY(QString searchQuery READ searchQuery WRITE setSearchQuery NOTIFY searchQueryChanged)
54 Q_PROPERTY(QString noResultsHint READ noResultsHint WRITE setNoResultsHint NOTIFY noResultsHintChanged)
54 Q_PROPERTY(QString noResultsHint READ noResultsHint WRITE setNoResultsHint NOTIFY noResultsHintChanged)
55+ Q_PROPERTY(QString formFactor READ formFactor WRITE setFormFactor NOTIFY formFactorChanged)
55
56
56public:
57public:
57 explicit Scope(QObject *parent = 0);
58 explicit Scope(QObject *parent = 0);
@@ -65,14 +66,15 @@ public:
65 bool visible() const;
66 bool visible() const;
66 QString shortcut() const;
67 QString shortcut() const;
67 bool connected() const;
68 bool connected() const;
68− DeeListModel* results() const;
69 Categories* categories() const;
69 Categories* categories() const;
70 QString searchQuery() const;
70 QString searchQuery() const;
71 QString noResultsHint() const;
71 QString noResultsHint() const;
72+ QString formFactor() const;
72
73
73 /* setters */
74 /* setters */
74 void setSearchQuery(const QString& search_query);
75 void setSearchQuery(const QString& search_query);
75 void setNoResultsHint(const QString& hint);
76 void setNoResultsHint(const QString& hint);
77+ void setFormFactor(const QString& form_factor);
76
78
77 Q_INVOKABLE void activate(const QVariant &uri, const QVariant &icon_hint, const QVariant &category,
79 Q_INVOKABLE void activate(const QVariant &uri, const QVariant &icon_hint, const QVariant &category,
78 const QVariant &result_type, const QVariant &mimetype, const QVariant &title,
80 const QVariant &result_type, const QVariant &mimetype, const QVariant &title,
@@ -94,11 +96,11 @@ Q_SIGNALS:
94 void visibleChanged(bool);
96 void visibleChanged(bool);
95 void shortcutChanged(const std::string&);
97 void shortcutChanged(const std::string&);
96 void connectedChanged(bool);
98 void connectedChanged(bool);
97− void resultsChanged();
98 void categoriesChanged();
99 void categoriesChanged();
99 void searchFinished(const std::string&, unity::glib::HintsMap const&, unity::glib::Error const&);
100 void searchFinished(const std::string&, unity::glib::HintsMap const&, unity::glib::Error const&);
100 void searchQueryChanged();
101 void searchQueryChanged();
101 void noResultsHintChanged();
102 void noResultsHintChanged();
103+ void formFactorChanged();
102
104
103 // signals triggered by activate(..) or preview(..) requests.
105 // signals triggered by activate(..) or preview(..) requests.
104 void previewReady(Preview *preview);
106 void previewReady(Preview *preview);
@@ -111,12 +113,6 @@ private Q_SLOTS:
111 void onSearchFinished(const std::string &, unity::glib::HintsMap const &);
113 void onSearchFinished(const std::string &, unity::glib::HintsMap const &);
112
114
113private:
115private:
114− void onResultsSwarmNameChanged(const std::string&);
115− void onResultsChanged(const unity::dash::Results::Ptr&);
116− void onResultsModelChanged(unity::glib::Object<DeeModel>);
117− void onCategoriesSwarmNameChanged(const std::string&);
118− void onCategoriesModelChanged(unity::glib::Object<DeeModel>);
119− void onCategoriesChanged(const unity::dash::Categories::Ptr&);
120 unity::dash::LocalResult createLocalResult(const QVariant &uri, const QVariant &icon_hint,
116 unity::dash::LocalResult createLocalResult(const QVariant &uri, const QVariant &icon_hint,
121 const QVariant &category, const QVariant &result_type,
117 const QVariant &category, const QVariant &result_type,
122 const QVariant &mimetype, const QVariant &title,
118 const QVariant &mimetype, const QVariant &title,
@@ -127,10 +123,10 @@ private:
127 void fallbackActivate(const QString& uri);
123 void fallbackActivate(const QString& uri);
128
124
129 unity::dash::Scope::Ptr m_unityScope;
125 unity::dash::Scope::Ptr m_unityScope;
130− DeeListModel* m_results;
131− Categories* m_categories;
126+ std::unique_ptr<Categories> m_categories;
132 QString m_searchQuery;
127 QString m_searchQuery;
133 QString m_noResultsHint;
128 QString m_noResultsHint;
129+ QString m_formFactor;
134};
130};
135
131
136Q_DECLARE_METATYPE(Scope*)
132Q_DECLARE_METATYPE(Scope*)
plugins/Unity/socialpreview.cppnew file+83
@@ -0,0 +1,83 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#include "socialpreview.h"
21+#include "socialpreviewcomment.h"
22+
23+#include <QDebug>
24+
25+SocialPreview::SocialPreview(QObject *parent):
26+ Preview(parent),
27+ m_unitySocialPreview(nullptr)
28+{
29+}
30+
31+QString SocialPreview::sender() const
32+{
33+ if (m_unitySocialPreview) {
34+ return QString::fromStdString(m_unitySocialPreview->sender());
35+ } else {
36+ qWarning() << "Preview not set";
37+ }
38+ return QString();
39+}
40+
41+QString SocialPreview::content() const
42+{
43+ if (m_unitySocialPreview) {
44+ return QString::fromStdString(m_unitySocialPreview->content());
45+ } else {
46+ qWarning() << "Preview not set";
47+ }
48+ return QString();
49+}
50+
51+QString SocialPreview::avatar() const
52+{
53+ if (m_unitySocialPreview) {
54+ return QString::fromUtf8(g_icon_to_string(m_unitySocialPreview->avatar()));
55+ } else {
56+ qWarning() << "Preview not set";
57+ }
58+ return QString();
59+}
60+
61+QVariant SocialPreview::comments()
62+{
63+ return QVariant::fromValue(m_comments);
64+}
65+
66+void SocialPreview::setUnityPreview(unity::dash::Preview::Ptr unityPreview)
67+{
68+ m_unitySocialPreview = std::dynamic_pointer_cast<unity::dash::SocialPreview>(unityPreview);
69+ qDeleteAll(m_comments);
70+ m_comments.clear();
71+
72+ if (m_unitySocialPreview) {
73+ for (auto unityComment: m_unitySocialPreview->GetComments()) {
74+ auto comment = new SocialPreviewComment(this);
75+ comment->setUnityComment(unityComment);
76+ m_comments.append(comment);
77+
78+ Q_EMIT previewChanged();
79+ }
80+ } else {
81+ qWarning() << "Incorrect preview type";
82+ }
83+}
plugins/Unity/socialpreview.hnew file+63
@@ -0,0 +1,63 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#ifndef SOCIALPREVIEW_H
21+#define SOCIALPREVIEW_H
22+
23+// local
24+#include "preview.h"
25+
26+// Qt
27+#include <QObject>
28+#include <QList>
29+#include <QMetaType>
30+
31+// libunity-core
32+#include <UnityCore/SocialPreview.h>
33+
34+class Q_DECL_EXPORT SocialPreview: public Preview
35+{
36+ Q_OBJECT
37+
38+ Q_PROPERTY(QString sender READ sender NOTIFY previewChanged)
39+ Q_PROPERTY(QString content READ content NOTIFY previewChanged)
40+ Q_PROPERTY(QString avatar READ avatar NOTIFY previewChanged)
41+
42+public:
43+ explicit SocialPreview(QObject *parent = 0);
44+
45+ QString sender() const;
46+ QString content() const;
47+ QString avatar() const;
48+ QVariant comments();
49+
50+Q_SIGNALS:
51+ void previewChanged();
52+
53+protected:
54+ void setUnityPreview(unity::dash::Preview::Ptr unityPreview) override;
55+
56+private:
57+ unity::dash::SocialPreview::Ptr m_unitySocialPreview;
58+ QList<QObject *> m_comments;
59+};
60+
61+Q_DECLARE_METATYPE(SocialPreview *)
62+
63+#endif
plugins/Unity/socialpreviewcomment.cppnew file+63
@@ -0,0 +1,63 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+// local
21+#include "socialpreviewcomment.h"
22+
23+SocialPreviewComment::SocialPreviewComment(QObject *parent) :
24+ QObject(parent)
25+{
26+}
27+
28+void SocialPreviewComment::setUnityComment(unity::dash::SocialPreview::CommentPtr unityComment)
29+{
30+ m_unityComment = unityComment;
31+}
32+
33+QString SocialPreviewComment::id() const
34+{
35+ if (m_unityComment) {
36+ return QString::fromStdString(m_unityComment->id);
37+ }
38+ return QString();
39+}
40+
41+QString SocialPreviewComment::displayName() const
42+{
43+ if (m_unityComment) {
44+ return QString::fromStdString(m_unityComment->display_name);
45+ }
46+ return QString();
47+}
48+
49+QString SocialPreviewComment::content() const
50+{
51+ if (m_unityComment) {
52+ return QString::fromStdString(m_unityComment->content);
53+ }
54+ return QString();
55+}
56+
57+QString SocialPreviewComment::time() const
58+{
59+ if (m_unityComment) {
60+ return QString::fromStdString(m_unityComment->time);
61+ }
62+ return QString();
63+}
plugins/Unity/socialpreviewcomment.hnew file+57
@@ -0,0 +1,57 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#ifndef SOCIALPREVIEWCOMMENT_H
21+#define SOCIALPREVIEWCOMMENT_H
22+
23+// Qt
24+#include <QObject>
25+#include <QMetaType>
26+
27+// libunity-core
28+#include <UnityCore/SocialPreview.h>
29+
30+class Q_DECL_EXPORT SocialPreviewComment : public QObject
31+{
32+ Q_OBJECT
33+
34+ Q_PROPERTY(QString id READ id NOTIFY socialPreviewCommentChanged)
35+ Q_PROPERTY(QString displayName READ displayName NOTIFY socialPreviewCommentChanged)
36+ Q_PROPERTY(QString content READ content NOTIFY socialPreviewCommentChanged)
37+ Q_PROPERTY(QString time READ time NOTIFY socialPreviewCommentChanged)
38+
39+public:
40+ explicit SocialPreviewComment(QObject *parent = 0);
41+ void setUnityComment(unity::dash::SocialPreview::CommentPtr unityComment);
42+
43+ QString id() const;
44+ QString displayName() const;
45+ QString content() const;
46+ QString time() const;
47+
48+Q_SIGNALS:
49+ void socialPreviewCommentChanged();
50+
51+private:
52+ unity::dash::SocialPreview::CommentPtr m_unityComment;
53+};
54+
55+Q_DECLARE_METATYPE(SocialPreviewComment *)
56+
57+#endif
plugins/Utils/CMakeLists.txt+2−12
@@ -23,15 +23,5 @@ set_target_properties(Utils-qml PROPERTIES COMPILE_FLAGS -fvisibility=default)
23
23
24qt5_use_modules(Utils-qml Qml Quick)
24qt5_use_modules(Utils-qml Qml Quick)
25
25
26−# copy qmldir file into build directory for shadow builds
26+# export the qmldir and qmltypes files
27−file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
28− DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
29− )
30−
31−install(TARGETS Utils-qml
27+export_qmlplugin(Utils 0.1 Utils TARGETS Utils-qml)
32− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/Utils
33− )
34−
35−install(FILES qmldir
36− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/Utils
37− )
plugins/Utils/qmldir+1
@@ -1,2 +1,3 @@
1module Utils
1module Utils
2plugin Utils-qml
2plugin Utils-qml
3+typeinfo plugin.qmltypes
po/es.po+7−31
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
10"POT-Creation-Date: 2013-06-26 22:58+0200\n"
11−"PO-Revision-Date: 2013-06-16 23:44+0000\n"
11+"PO-Revision-Date: 2013-07-08 07:25+0000\n"
12"Last-Translator: Adolfo Jayme Barrientos <fitoschido@gmail.com>\n"
12"Last-Translator: Adolfo Jayme Barrientos <fitoschido@gmail.com>\n"
13"Language-Team: Spanish <es@li.org>\n"
13"Language-Team: Spanish <es@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-06-27 16:16+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-09 06:13+0000\n"
18−"X-Generator: Launchpad (build 16681)\n"
18+"X-Generator: Launchpad (build 16696)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
@@ -167,16 +167,16 @@ msgstr "Autor:"
167
167
168#: Greeter/Lockscreen.qml:133
168#: Greeter/Lockscreen.qml:133
169msgid "Emergency call"
169msgid "Emergency call"
170−msgstr ""
170+msgstr "Llamada de emergencia"
171
171
172#: Greeter/PassphraseLockscreen.qml:59
172#: Greeter/PassphraseLockscreen.qml:59
173#, qt-format
173#, qt-format
174msgid "Hello %1"
174msgid "Hello %1"
175−msgstr ""
175+msgstr "Hola %1"
176
176
177#: Greeter/PassphraseLockscreen.qml:59
177#: Greeter/PassphraseLockscreen.qml:59
178msgid "Hello"
178msgid "Hello"
179−msgstr ""
179+msgstr "Hola"
180
180
181#: Hud/HudParametrizedActionsPage.qml:132
181#: Hud/HudParametrizedActionsPage.qml:132
182msgid "Confirm"
182msgid "Confirm"
@@ -217,28 +217,4 @@ msgstr "No hay nada que coincida con su búsqueda."
217#: Shell.qml:383
217#: Shell.qml:383
218#, qt-format
218#, qt-format
219msgid "Please enter %1"
219msgid "Please enter %1"
220−msgstr ""
220+msgstr "Introduzca %1"
221−
222−#~ msgid "People"
223−#~ msgstr "Gente"
224−
225−#~ msgid "Home screen"
226−#~ msgstr "Pantalla de inicio"
227−
228−#~ msgid "Favourite People"
229−#~ msgstr "Gente favorita"
230−
231−#~ msgid "People Recently in Touch"
232−#~ msgstr "Gente contactada recientemente"
233−
234−#~ msgid "Recently in touch"
235−#~ msgstr "Contactados recientemente"
236−
237−#~ msgid "Favourites"
238−#~ msgstr "Favoritos"
239−
240−#~ msgid "A-Z"
241−#~ msgstr "A-Z"
242−
243−#~ msgid "New Contacts"
244−#~ msgstr "Contactos nuevos"
run_on_device+1−3
@@ -65,11 +65,9 @@ setup_adb_forwarding() {
65}
65}
66
66
67install_dependencies() {
67install_dependencies() {
68+ exec_with_adb apt-get update
68 exec_with_adb apt-get -y install openssh-server
69 exec_with_adb apt-get -y install openssh-server
69 exec_with_ssh $SUDO apt-get -y install build-essential rsync bzr ccache gdb ninja-build devscripts equivs
70 exec_with_ssh $SUDO apt-get -y install build-essential rsync bzr ccache gdb ninja-build devscripts equivs
70− exec_with_ssh $SUDO add-apt-repository -y ppa:canonical-qt5-edgers/qt5-proper
71− exec_with_ssh $SUDO add-apt-repository -s -y ppa:phablet-team/ppa
72− exec_with_ssh $SUDO apt-get update
73}
71}
74
72
75sync_code() {
73sync_code() {
src/Panel/Indicators/client/indicatorsclient.cpp+20−10
@@ -56,6 +56,26 @@ IndicatorsClient::IndicatorsClient(int &argc, char **argv)
56 m_view(0)
56 m_view(0)
57{
57{
58 m_application = new QApplication(argc, argv);
58 m_application = new QApplication(argc, argv);
59+ QStringList args = m_application->arguments();
60+
61+ m_view = new QQuickView;
62+ m_view->engine()->setBaseUrl(QUrl::fromLocalFile(::shellAppDirectory()+"Panel/Indicators/client/"));
63+ prependImportPaths(m_view->engine(), ::overrideImportPaths());
64+ appendImportPaths(m_view->engine(), ::fallbackImportPaths());
65+
66+ m_view->setSource(QUrl("IndicatorsClient.qml"));
67+ m_view->setResizeMode(QQuickView::SizeRootObjectToView);
68+
69+ if (args.contains(QLatin1String("-geometry")) && args.size() > args.indexOf(QLatin1String("-geometry")) + 1) {
70+ QStringList geometryArg = args.at(args.indexOf(QLatin1String("-geometry")) + 1).split('x');
71+ if (geometryArg.size() == 2) {
72+ m_view->resize(geometryArg.at(0).toInt(), geometryArg.at(1).toInt());
73+ }
74+ }
75+ else {
76+ //Usable size on desktop
77+ m_view->setMinimumSize(QSize(480, 720));
78+ }
59}
79}
60
80
61IndicatorsClient::~IndicatorsClient()
81IndicatorsClient::~IndicatorsClient()
@@ -69,21 +89,11 @@ IndicatorsClient::~IndicatorsClient()
69
89
70void IndicatorsClient::setupUI()
90void IndicatorsClient::setupUI()
71{
91{
72− m_view = new QQuickView;
73− m_view->engine()->setBaseUrl(QUrl::fromLocalFile(::shellAppDirectory()+"Panel/Indicators/client/"));
74− prependImportPaths(m_view->engine(), ::overrideImportPaths());
75− appendImportPaths(m_view->engine(), ::fallbackImportPaths());
76−
77− m_view->setSource(QUrl("IndicatorsClient.qml"));
78− m_view->setResizeMode(QQuickView::SizeRootObjectToView);
79
92
80− //Usable size on desktop
81− m_view->setMinimumSize(QSize(480, 720));
82}
93}
83
94
84int IndicatorsClient::run()
95int IndicatorsClient::run()
85{
96{
86− setupUI();
87 m_view->show();
97 m_view->show();
88 return m_application->exec();
98 return m_application->exec();
89}
99}
tests/autopilot/unity8/indicators_client/__init__.pynew file+8
@@ -0,0 +1,8 @@
1+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2+# Copyright 2013 Canonical
3+#
4+# This program is free software: you can redistribute it and/or modify it
5+# under the terms of the GNU General Public License version 3, as published
6+# by the Free Software Foundation.
7+
8+"""unity8 indicators-client autopilot tests and emulators - sub level package."""
tests/autopilot/indicators_client/emulators/__init__.py → tests/autopilot/unity8/indicators_client/emulators/__init__.pyrenamed

The content is the same.

tests/autopilot/indicators_client/emulators/common.py → tests/autopilot/unity8/indicators_client/emulators/common.pyrenamed

The content is the same.

tests/autopilot/indicators_client/emulators/main_window.py → tests/autopilot/unity8/indicators_client/emulators/main_window.pyrenamed−2
@@ -5,8 +5,6 @@
5# under the terms of the GNU General Public License version 3, as published
5# under the terms of the GNU General Public License version 3, as published
6# by the Free Software Foundation.
6# by the Free Software Foundation.
7
7
8−from indicators_client.emulators import IndicatorsIntrospectionObject
9−
10class MainWindow(object):
8class MainWindow(object):
11 """An emulator class that makes it easy to interact with the shell"""
9 """An emulator class that makes it easy to interact with the shell"""
12
10
tests/autopilot/indicators_client/tests/__init__.py → tests/autopilot/unity8/indicators_client/tests/__init__.pyrenamed+22−8
@@ -15,7 +15,7 @@ from autopilot.matchers import Eventually
15from autopilot.platform import model
15from autopilot.platform import model
16from testtools.matchers import Equals
16from testtools.matchers import Equals
17
17
18−from indicators_client.emulators.main_window import MainWindow
18+from unity8.indicators_client.emulators.main_window import MainWindow
19from logging import getLogger
19from logging import getLogger
20import sys
20import sys
21from time import sleep
21from time import sleep
@@ -38,19 +38,33 @@ class IndicatorsTestCase(AutopilotTestCase):
38 ('with touch', dict(input_device_class=Touch)),
38 ('with touch', dict(input_device_class=Touch)),
39 ]
39 ]
40
40
41− def setUp(self):
41+ def setUp(self, geometry, grid_size):
42 self.pointing_device = Pointer(self.input_device_class.create())
42 self.pointing_device = Pointer(self.input_device_class.create())
43 super(IndicatorsTestCase, self).setUp()
43 super(IndicatorsTestCase, self).setUp()
44+ if grid_size != "0":
45+ os.environ['GRID_UNIT_PX'] = grid_size
46+ self.grid_size = int(grid_size)
47+ else:
48+ self.grid_size = int(os.environ['GRID_UNIT_PX'])
49+
44 if os.path.realpath(__file__).startswith("/usr/"):
50 if os.path.realpath(__file__).startswith("/usr/"):
45− self.launch_test_installed()
51+ self.launch_test_installed(geometry)
46 else:
52 else:
47− self.launch_test_local()
53+ self.launch_test_local(geometry)
48
54
49− def launch_test_local(self):
55+ def launch_test_local(self, geometry):
56+ if geometry != "0x0":
50− self.app = self.launch_test_application("../../builddir/src/Panel/Indicators/client/indicators-client", app_type='qt')
57+ self.app = self.launch_test_application("../../builddir/src/Panel/Indicators/client/indicators-client",
58+ "-geometry", geometry, app_type='qt')
59+ else:
60+ self.app = self.launch_test_application("../../builddir/src/Panel/Indicators/client/indicators-client",
61+ app_type='qt')
51
62
52− def launch_test_installed(self):
63+ def launch_test_installed(self, geometry):
64+ if geometry != "0x0":
65+ self.app = self.launch_test_application("indicators-client", "-geometry", geometry, app_type='qt')
66+ else:
53− self.app = self.launch_test_application("indicators-client", app_type='qt')
67+ self.app = self.launch_test_application("indicators-client", app_type='qt')
54
68
55 def skipWrapper(*args, **kwargs):
69 def skipWrapper(*args, **kwargs):
56 pass
70 pass
tests/autopilot/indicators_client/tests/test_battery.py → tests/autopilot/unity8/indicators_client/tests/test_battery.pyrenamed+14−11
@@ -10,30 +10,30 @@
10from testtools.matchers import Equals, NotEquals
10from testtools.matchers import Equals, NotEquals
11from autopilot.matchers import Eventually
11from autopilot.matchers import Eventually
12
12
13−from indicators_client.tests import IndicatorsTestCase
13+from unity8.indicators_client.tests import IndicatorsTestCase
14from time import sleep
14from time import sleep
15import random
15import random
16import math
16import math
17
17
18class TestDisplayMenus(IndicatorsTestCase):
18class TestDisplayMenus(IndicatorsTestCase):
19 def setUp(self):
19 def setUp(self):
20− super(TestDisplayMenus, self).setUp()
20+ super(TestDisplayMenus, self).setUp("400x800", "12")
21
21
22 # This opens the messaging menu so you don't have to do that in
22 # This opens the messaging menu so you don't have to do that in
23 # every test case
23 # every test case
24− battery_menu = self.main_window.get_battery_menu()
24+ self.assertThat(lambda: self.main_window.get_battery_menu(), Eventually(NotEquals(None)));
25− self.pointing_device.move_to_object(battery_menu)
25+ self.pointing_device.move_to_object(self.main_window.get_battery_menu())
26 self.pointing_device.click()
26 self.pointing_device.click()
27
27
28− self.page = self.app.select_single("IndicatorsPage");
29− page_loader = self.app.select_single("IndicatorsPage/QQuickLoader", objectName="page_loader");
28+ fn_loader = lambda: self.app.select_single("IndicatorsPage/QQuickLoader", objectName="page_loader");
29+ self.assertThat(fn_loader, Eventually(NotEquals(None)));
30+ page_loader = fn_loader();
30 self.assertThat(page_loader.progress, Eventually(Equals(1.0)))
31 self.assertThat(page_loader.progress, Eventually(Equals(1.0)))
31
32
32 def tearDown(self):
33 def tearDown(self):
33 # self.main_window.get_indicators_client().reset()
34 # self.main_window.get_indicators_client().reset()
34 super(TestDisplayMenus, self).tearDown()
35 super(TestDisplayMenus, self).tearDown()
35
36
36−
37 # START SECTION
37 # START SECTION
38 # We need to move these to emulators once autopilot supports emulators for
38 # We need to move these to emulators once autopilot supports emulators for
39 # applications started with AutopilotTestCase.launch_test_application
39 # applications started with AutopilotTestCase.launch_test_application
@@ -67,8 +67,10 @@ class TestDisplayMenus(IndicatorsTestCase):
67 def test_auto_bright_switch(self):
67 def test_auto_bright_switch(self):
68 """Test the auto-bright switch"""
68 """Test the auto-bright switch"""
69
69
70+ # wait for the switch menu item
70− auto_brightness = self.app.select_single("SwitchMenuItem", objectName="auto-brightness")
71+ fn_auto_brightness = lambda: self.app.select_single("SwitchMenuItem", objectName="auto-brightness");
71− self.assertThat(auto_brightness, NotEquals(None))
72+ self.assertThat(fn_auto_brightness, Eventually(NotEquals(None)));
73+ auto_brightness = fn_auto_brightness();
72
74
73 old_ab_value = auto_brightness.checked
75 old_ab_value = auto_brightness.checked
74
76
@@ -80,8 +82,9 @@ class TestDisplayMenus(IndicatorsTestCase):
80 def test_brightness_slider(self):
82 def test_brightness_slider(self):
81 """Test the auto-bright switch"""
83 """Test the auto-bright switch"""
82
84
83− brightness_menu = self.app.select_single("SliderMenuItem", objectName="brightness")
85+ fn_brightness_menu = lambda: self.app.select_single("SliderMenuItem", objectName="brightness");
84− self.assertThat(brightness_menu, NotEquals(None))
86+ self.assertThat(fn_brightness_menu, Eventually(NotEquals(None)));
87+ brightness_menu = fn_brightness_menu();
85
88
86 old_ab_value = brightness_menu.value
89 old_ab_value = brightness_menu.value
87 # find a new value to do to. At least 1/4 distance away from current value
90 # find a new value to do to. At least 1/4 distance away from current value
tests/autopilot/indicators_client/__init__.py → tests/autopilot/unity8/shell/__init__.pyrenamed+1−1
@@ -5,4 +5,4 @@
5# under the terms of the GNU General Public License version 3, as published
5# under the terms of the GNU General Public License version 3, as published
6# by the Free Software Foundation.
6# by the Free Software Foundation.
7
7
8−"""indicators-client autopilot tests and emulators - top level package."""
8+"""unity8 shell autopilot tests and emulators - sub level package."""
tests/autopilot/unity8/emulators/__init__.py → tests/autopilot/unity8/shell/emulators/__init__.pyrenamed

The content is the same.

tests/autopilot/unity8/emulators/main_window.py → tests/autopilot/unity8/shell/emulators/main_window.pyrenamed

The content is the same.

tests/autopilot/unity8/tests/__init__.py → tests/autopilot/unity8/shell/tests/__init__.pyrenamed+1−1
@@ -15,7 +15,7 @@ from autopilot.matchers import Eventually
15from autopilot.platform import model
15from autopilot.platform import model
16from testtools.matchers import Equals
16from testtools.matchers import Equals
17
17
18−from unity8.emulators.main_window import MainWindow
18+from unity8.shell.emulators.main_window import MainWindow
19
19
20class FormFactors(object):
20class FormFactors(object):
21 Phone, Tablet, Desktop = range(3)
21 Phone, Tablet, Desktop = range(3)
tests/autopilot/unity8/tests/helpers.py → tests/autopilot/unity8/shell/tests/helpers.pyrenamed

The content is the same.

tests/autopilot/unity8/tests/testbigscreen.py → tests/autopilot/unity8/shell/tests/testbigscreen.pyrenamed+1−1
@@ -10,7 +10,7 @@
10from testtools.matchers import Equals
10from testtools.matchers import Equals
11from autopilot.matchers import Eventually
11from autopilot.matchers import Eventually
12
12
13−from unity8.tests import ShellTestCase
13+from unity8.shell.tests import ShellTestCase
14
14
15class TestBig(ShellTestCase):
15class TestBig(ShellTestCase):
16 def setUp(self):
16 def setUp(self):
tests/autopilot/unity8/tests/testhud.py → tests/autopilot/unity8/shell/tests/testhud.pyrenamed+2−2
@@ -25,8 +25,8 @@
25
25
26from __future__ import absolute_import
26from __future__ import absolute_import
27
27
28−from unity8.tests import ShellTestCase, FormFactors
28+from unity8.shell.tests import ShellTestCase, FormFactors
29−from unity8.tests.helpers import TestShellHelpers
29+from unity8.shell.tests.helpers import TestShellHelpers
30
30
31from autopilot.input import Mouse, Touch, Pointer
31from autopilot.input import Mouse, Touch, Pointer
32from testtools.matchers import Equals, NotEquals, GreaterThan, MismatchError
32from testtools.matchers import Equals, NotEquals, GreaterThan, MismatchError
tests/autopilot/unity8/tests/testlockscreen.py → tests/autopilot/unity8/shell/tests/testlockscreen.pyrenamed+2−2
@@ -25,8 +25,8 @@
25
25
26from __future__ import absolute_import
26from __future__ import absolute_import
27
27
28−from unity8.tests import ShellTestCase, FormFactors
28+from unity8.shell.tests import ShellTestCase, FormFactors
29−from unity8.tests.helpers import TestShellHelpers
29+from unity8.shell.tests.helpers import TestShellHelpers
30
30
31from autopilot.input import Mouse, Touch, Pointer
31from autopilot.input import Mouse, Touch, Pointer
32from testtools.matchers import Equals, NotEquals, GreaterThan, MismatchError
32from testtools.matchers import Equals, NotEquals, GreaterThan, MismatchError
tests/mocks/LightDM/demo/InfographicModelPrivate.cpp+3−3
@@ -54,7 +54,7 @@ void InfographicModelPrivate::generateFakeData()
54 QSharedPointer<InfographicData> data(
54 QSharedPointer<InfographicData> data(
55 new InfographicData("<b>52km</b> travelled", yellowTheme, firstMonth,
55 new InfographicData("<b>52km</b> travelled", yellowTheme, firstMonth,
56 orangeTheme, secondMonth, this));
56 orangeTheme, secondMonth, this));
57− m_fakeData.insert("guest", data);
57+ m_fakeData.insert("phablet", data);
58 }
58 }
59
59
60 {
60 {
@@ -69,7 +69,7 @@ void InfographicModelPrivate::generateFakeData()
69 QSharedPointer<InfographicData> data(
69 QSharedPointer<InfographicData> data(
70 new InfographicData("<b>33</b> messages today", pinkTheme,
70 new InfographicData("<b>33</b> messages today", pinkTheme,
71 firstMonth, orangeTheme, secondMonth, this));
71 firstMonth, orangeTheme, secondMonth, this));
72− m_fakeData.insert("guest", data);
72+ m_fakeData.insert("phablet", data);
73 }
73 }
74
74
75 {
75 {
@@ -84,7 +84,7 @@ void InfographicModelPrivate::generateFakeData()
84 QSharedPointer<InfographicData> data(
84 QSharedPointer<InfographicData> data(
85 new InfographicData("<b>69</b> minutes talk time", darkPurpleTheme,
85 new InfographicData("<b>69</b> minutes talk time", darkPurpleTheme,
86 firstMonth, redTheme, secondMonth, this));
86 firstMonth, redTheme, secondMonth, this));
87− m_fakeData.insert("guest", data);
87+ m_fakeData.insert("phablet", data);
88 }
88 }
89}
89}
90
90
tests/mocks/LightDM/demo/UsersModelPrivate.cpp+1−1
@@ -26,7 +26,7 @@ UsersModelPrivate::UsersModelPrivate(UsersModel* parent)
26{
26{
27 entries =
27 entries =
28 {
28 {
29− { "single", "Guest", 0, 0, false, false, 0, 0 },
29+ { "phablet", "Guest", 0, 0, false, false, 0, 0 },
30 };
30 };
31}
31}
32
32
tests/mocks/Unity/CMakeLists.txt+4−4
@@ -21,13 +21,11 @@ include_directories(
21add_definitions(-DQT_NO_KEYWORDS)
21add_definitions(-DQT_NO_KEYWORDS)
22
22
23set(UnityQML_SOURCES
23set(UnityQML_SOURCES
24− ${CMAKE_SOURCE_DIR}/plugins/Unity/categories.cpp
24+ ${CMAKE_SOURCE_DIR}/plugins/Unity/categoryresults.cpp
25− ${CMAKE_SOURCE_DIR}/plugins/Unity/categoryfilter.cpp
26− ${CMAKE_SOURCE_DIR}/plugins/Utils/qsortfilterproxymodelqml.cpp
27 fake_scope.cpp
25 fake_scope.cpp
28 fake_scopes.cpp
26 fake_scopes.cpp
27+ fake_categories.cpp
29 fake_unity_plugin.cpp
28 fake_unity_plugin.cpp
30− fake_launchermodel.cpp
31)
29)
32
30
33add_library(FakeUnityQml MODULE ${UnityQML_SOURCES})
31add_library(FakeUnityQml MODULE ${UnityQML_SOURCES})
@@ -44,3 +42,5 @@ qt5_use_modules(FakeUnityQml Qml)
44file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
42file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
45 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
43 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
46 )
44 )
45+
46+add_subdirectory(Launcher)
tests/mocks/Unity/Launcher/CMakeLists.txtnew file+26
@@ -0,0 +1,26 @@
1+include(FindPkgConfig)
2+pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=2)
3+
4+include_directories(
5+ ${CMAKE_CURRENT_SOURCE_DIR}
6+)
7+
8+set(MockLauncherModel_SOURCES
9+ ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherItemInterface.h
10+ ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherModelInterface.h
11+ ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/QuickListModelInterface.h
12+ plugin.cpp
13+ MockLauncherModel.cpp
14+ MockLauncherItem.cpp
15+ MockQuickListModel.cpp
16+)
17+
18+add_library(MockLauncherPlugin MODULE ${MockLauncherModel_SOURCES})
19+
20+qt5_use_modules(MockLauncherPlugin Core Quick)
21+
22+# copy files into build directory for shadow builds
23+add_custom_target(LauncherPluginQmlDirFile ALL
24+ COMMAND cp "${CMAKE_CURRENT_SOURCE_DIR}/qmldir" ${CMAKE_CURRENT_BINARY_DIR}
25+ DEPENDS qmldir
26+)
tests/mocks/Unity/Launcher/MockLauncherItem.cppnew file+134
@@ -0,0 +1,134 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Michael Zanetti <michael.zanetti@canonical.com>
18+ */
19+
20+#include "MockLauncherItem.h"
21+#include "MockQuickListModel.h"
22+
23+using namespace unity::shell::launcher;
24+
25+MockLauncherItem::MockLauncherItem(const QString &appId, const QString& desktopFile, const QString& name, const QString& icon, QObject* parent):
26+ LauncherItemInterface(parent),
27+ m_appId(appId),
28+ m_desktopFile(desktopFile),
29+ m_name(name),
30+ m_icon(icon),
31+ m_pinned(false),
32+ m_running(false),
33+ m_recent(false),
34+ m_progress(8),
35+ m_count(8),
36+ m_quickList(new MockQuickListModel(this))
37+{
38+
39+}
40+
41+QString MockLauncherItem::appId() const
42+{
43+ return m_appId;
44+}
45+
46+QString MockLauncherItem::desktopFile() const
47+{
48+ return m_desktopFile;
49+}
50+
51+QString MockLauncherItem::name() const
52+{
53+ return m_name;
54+}
55+
56+QString MockLauncherItem::icon() const
57+{
58+ return m_icon;
59+}
60+
61+bool MockLauncherItem::pinned() const
62+{
63+ return m_pinned;
64+}
65+
66+void MockLauncherItem::setPinned(bool pinned)
67+{
68+ if (m_pinned != pinned)
69+ {
70+ m_pinned = pinned;
71+ Q_EMIT pinnedChanged(m_pinned);
72+ }
73+}
74+
75+bool MockLauncherItem::running() const
76+{
77+ return m_running;
78+}
79+
80+void MockLauncherItem::setRunning(bool running)
81+{
82+ if (m_running != running)
83+ {
84+ m_running = running;
85+ Q_EMIT runningChanged(running);
86+ }
87+}
88+
89+bool MockLauncherItem::recent() const
90+{
91+ return m_recent;
92+}
93+
94+void MockLauncherItem::setRecent(bool recent)
95+{
96+ if (m_recent != recent)
97+ {
98+ m_recent = recent;
99+ Q_EMIT recentChanged(recent);
100+ }
101+}
102+
103+int MockLauncherItem::progress() const
104+{
105+ return m_progress;
106+}
107+
108+void MockLauncherItem::setProgress(int progress)
109+{
110+ if (m_progress != progress)
111+ {
112+ m_progress = progress;
113+ Q_EMIT progressChanged(progress);
114+ }
115+}
116+
117+int MockLauncherItem::count() const
118+{
119+ return m_count;
120+}
121+
122+void MockLauncherItem::setCount(int count)
123+{
124+ if (m_count != count)
125+ {
126+ m_count = count;
127+ Q_EMIT countChanged(count);
128+ }
129+}
130+
131+unity::shell::launcher::QuickListModelInterface *MockLauncherItem::quickList() const
132+{
133+ return m_quickList;
134+}
tests/mocks/Unity/Launcher/MockLauncherItem.hnew file+70
@@ -0,0 +1,70 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Michael Zanetti <michael.zanetti@canonical.com>
18+ */
19+
20+#ifndef MOCKLAUNCHERITEM_H
21+#define MOCKLAUNCHERITEM_H
22+
23+#include <unity/shell/launcher/LauncherItemInterface.h>
24+
25+class MockQuickListModel;
26+
27+using namespace unity::shell::launcher;
28+
29+class MockLauncherItem: public LauncherItemInterface
30+{
31+ Q_OBJECT
32+public:
33+ MockLauncherItem(const QString &appId, const QString& desktopFile, const QString& name, const QString& icon, QObject* parent = 0);
34+
35+ QString appId() const;
36+ QString desktopFile() const;
37+ QString name() const;
38+ QString icon() const;
39+
40+ bool pinned() const;
41+ void setPinned(bool pinned);
42+
43+ bool running() const;
44+ void setRunning(bool running);
45+
46+ bool recent() const;
47+ void setRecent(bool recent);
48+
49+ int progress() const;
50+ void setProgress(int progress);
51+
52+ int count() const;
53+ void setCount(int count);
54+
55+ unity::shell::launcher::QuickListModelInterface *quickList() const;
56+
57+private:
58+ QString m_appId;
59+ QString m_desktopFile;
60+ QString m_name;
61+ QString m_icon;
62+ bool m_pinned;
63+ bool m_running;
64+ bool m_recent;
65+ int m_progress;
66+ int m_count;
67+ MockQuickListModel *m_quickList;
68+};
69+
70+#endif // MOCKLAUNCHERITEM_H
tests/mocks/Unity/Launcher/MockLauncherModel.cppnew file+152
@@ -0,0 +1,152 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Michael Zanetti <michael.zanetti@canonical.com>
18+ */
19+
20+#include "MockLauncherModel.h"
21+#include "MockLauncherItem.h"
22+
23+MockLauncherModel::MockLauncherModel(QObject* parent): LauncherModelInterface(parent)
24+{
25+ MockLauncherItem *item = new MockLauncherItem("phone-app", "/usr/share/applications/phone-app.desktop", "Phone", "phone-app");
26+ m_list.append(item);
27+ item = new MockLauncherItem("camera-app", "/usr/share/applications/camera-app.desktop", "Camera", "camera");
28+ m_list.append(item);
29+ item = new MockLauncherItem("gallery-app", "/usr/share/applications/gallery-app.desktop", "Gallery", "gallery");
30+ m_list.append(item);
31+ item = new MockLauncherItem("facebook-webapp", "/usr/share/applications/facebook-webapp.desktop", "Facebook", "facebook");
32+ m_list.append(item);
33+ item = new MockLauncherItem("webbrowser-app", "/usr/share/applications/webbrowser-app.desktop", "Browser", "browser");
34+ m_list.append(item);
35+ item = new MockLauncherItem("twitter-webapp", "/usr/share/applications/twitter-webapp.desktop", "Twitter", "twitter");
36+ m_list.append(item);
37+ item = new MockLauncherItem("gmail-webapp", "/usr/share/applications/gmail-webapp.desktop", "GMail", "gmail");
38+ m_list.append(item);
39+ item = new MockLauncherItem("ubuntu-weather-app", "/usr/share/applications/ubuntu-weather-app.desktop", "Weather", "weather");
40+ m_list.append(item);
41+ item = new MockLauncherItem("notes-app", "/usr/share/applications/notes-app.desktop", "Notepad", "notepad");
42+ m_list.append(item);
43+ item = new MockLauncherItem("ubuntu-calendar-app", "/usr/share/applications/ubuntu-calendar-app.desktop","Calendar", "calendar");
44+ m_list.append(item);
45+}
46+
47+MockLauncherModel::~MockLauncherModel()
48+{
49+ while (!m_list.empty())
50+ {
51+ m_list.takeFirst()->deleteLater();
52+ }
53+}
54+
55+int MockLauncherModel::rowCount(const QModelIndex& parent) const
56+{
57+ Q_UNUSED(parent)
58+ return m_list.count();
59+}
60+
61+QVariant MockLauncherModel::data(const QModelIndex& index, int role) const
62+{
63+ LauncherItemInterface *item = m_list.at(index.row());
64+ switch(role)
65+ {
66+ case RoleDesktopFile:
67+ return item->desktopFile();
68+ case RoleName:
69+ return item->name();
70+ case RoleIcon:
71+ return item->icon();
72+ case RolePinned:
73+ return item->pinned();
74+ case RoleRunning:
75+ return item->running();
76+ case RoleRecent:
77+ return item->recent();
78+ case RoleProgress:
79+ return item->progress();
80+ case RoleCount:
81+ return item->count();
82+ }
83+
84+ return QVariant();
85+}
86+
87+unity::shell::launcher::LauncherItemInterface *MockLauncherModel::get(int index) const
88+{
89+ if (index < 0 || index >= m_list.count())
90+ {
91+ return 0;
92+ }
93+ return m_list.at(index);
94+}
95+
96+void MockLauncherModel::move(int oldIndex, int newIndex)
97+{
98+ beginMoveRows(QModelIndex(), oldIndex, oldIndex, QModelIndex(), newIndex);
99+ m_list.move(oldIndex, newIndex);
100+ endMoveRows();
101+}
102+
103+void MockLauncherModel::pin(const QString &appId, int index)
104+{
105+ int currentIndex = findApp(appId);
106+
107+ if (currentIndex >= 0) {
108+ if (index == -1 || index == currentIndex) {
109+ m_list.at(currentIndex)->setPinned(true);
110+ QModelIndex modelIndex = this->index(currentIndex);
111+ Q_EMIT dataChanged(modelIndex, modelIndex);
112+ } else {
113+ move(currentIndex, index);
114+ }
115+ } else {
116+ beginInsertRows(QModelIndex(), index, index);
117+ m_list.insert(index, new MockLauncherItem(appId,
118+ appId + ".desktop",
119+ appId,
120+ appId + ".png"));
121+ m_list.at(index)->setPinned(true);
122+ endInsertRows();
123+ }
124+}
125+
126+void MockLauncherModel::requestRemove(const QString &appId)
127+{
128+ int index = findApp(appId);
129+ if (index >= 0) {
130+ beginRemoveRows(QModelIndex(), index, 0);
131+ m_list.takeAt(index)->deleteLater();
132+ endRemoveRows();
133+ }
134+}
135+
136+void MockLauncherModel::quickListActionInvoked(const QString &appId, int actionIndex)
137+{
138+ Q_UNUSED(appId)
139+ Q_UNUSED(actionIndex)
140+ // Nothing to mock yet...
141+}
142+
143+int MockLauncherModel::findApp(const QString &appId)
144+{
145+ for (int i = 0; i < m_list.count(); ++i) {
146+ MockLauncherItem *item = m_list.at(i);
147+ if (item->appId() == appId) {
148+ return i;
149+ }
150+ }
151+ return -1;
152+}
tests/mocks/Unity/Launcher/MockLauncherModel.hnew file+54
@@ -0,0 +1,54 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Michael Zanetti <michael.zanetti@canonical.com>
18+ */
19+
20+#ifndef MOCKLAUNCHERMODEL_H
21+#define MOCKLAUNCHERMODEL_H
22+
23+#include <unity/shell/launcher/LauncherModelInterface.h>
24+
25+class MockLauncherItem;
26+
27+using namespace unity::shell::launcher;
28+
29+class MockLauncherModel: public LauncherModelInterface
30+{
31+ Q_OBJECT
32+
33+public:
34+ MockLauncherModel(QObject* parent = 0);
35+ ~MockLauncherModel();
36+
37+ int rowCount(const QModelIndex& parent) const;
38+
39+ QVariant data(const QModelIndex& index, int role) const;
40+
41+ Q_INVOKABLE unity::shell::launcher::LauncherItemInterface *get(int index) const;
42+ Q_INVOKABLE void move(int oldIndex, int newIndex);
43+ Q_INVOKABLE void pin(const QString &appId, int index = -1);
44+ Q_INVOKABLE void requestRemove(const QString &appId);
45+ Q_INVOKABLE void quickListActionInvoked(const QString &appId, int actionIndex);
46+
47+private:
48+ int findApp(const QString &appId);
49+
50+private:
51+ QList<MockLauncherItem*> m_list;
52+};
53+
54+#endif // MOCKLAUNCHERMODEL_H
tests/mocks/Unity/Launcher/MockQuickListModel.cppnew file+46
@@ -0,0 +1,46 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Michael Zanetti <michael.zanetti@canonical.com>
18+ */
19+
20+#include <MockQuickListModel.h>
21+
22+using namespace unity::shell::launcher;
23+
24+MockQuickListModel::MockQuickListModel(QObject *parent) :
25+ QuickListModelInterface(parent)
26+{
27+
28+}
29+
30+QVariant MockQuickListModel::data(const QModelIndex &index, int role) const
31+{
32+ switch (role)
33+ {
34+ case RoleLabel:
35+ return QLatin1String("test menu entry ") + QString::number(index.row());
36+ case RoleIcon:
37+ return QLatin1String("copy.png");
38+ }
39+ return QVariant();
40+}
41+
42+int MockQuickListModel::rowCount(const QModelIndex &parent) const
43+{
44+ Q_UNUSED(parent)
45+ return 4;
46+}
tests/mocks/Unity/Launcher/MockQuickListModel.hnew file+38
@@ -0,0 +1,38 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Michael Zanetti <michael.zanetti@canonical.com>
18+ */
19+
20+#ifndef MOCKQUICKLISTMODEL_H
21+#define MOCKQUICKLISTMODEL_H
22+
23+#include <unity/shell/launcher/QuickListModelInterface.h>
24+
25+using namespace unity::shell::launcher;
26+
27+class MockQuickListModel: public QuickListModelInterface
28+{
29+ Q_OBJECT
30+public:
31+ MockQuickListModel(QObject *parent = 0);
32+
33+ QVariant data(const QModelIndex &index, int role) const;
34+
35+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
36+};
37+
38+#endif // MOCKQUICKLISTMODEL_H
tests/mocks/Unity/Launcher/plugin.cppnew file+45
@@ -0,0 +1,45 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Michael Zanetti <michael.zanetti@canonical.com>
18+ */
19+
20+#include "plugin.h"
21+#include "MockLauncherModel.h"
22+#include "MockLauncherItem.h"
23+
24+#include <unity/shell/launcher/LauncherModelInterface.h>
25+#include <unity/shell/launcher/LauncherItemInterface.h>
26+
27+#include <QtQml/qqml.h>
28+
29+using namespace unity::shell::launcher;
30+
31+static QObject* modelProvider(QQmlEngine* /* engine */, QJSEngine* /* scriptEngine */)
32+{
33+ return new MockLauncherModel();
34+}
35+
36+// cppcheck-suppress unusedFunction
37+void TestLauncherPlugin::registerTypes(const char* uri)
38+{
39+ // @uri Unity.Launcher
40+ qmlRegisterUncreatableType<LauncherModelInterface>(uri, 0, 1, "LauncherModelInterface", "Abstract Interface. Cannot be instantiated.");
41+ qmlRegisterUncreatableType<LauncherItemInterface>(uri, 0, 1, "LauncherItemInterface", "Abstract Interface. Cannot be instantiated.");
42+
43+ qmlRegisterSingletonType<MockLauncherModel>(uri, 0, 1, "LauncherModel", modelProvider);
44+ qmlRegisterUncreatableType<MockLauncherItem>(uri, 0, 1, "LauncherItem", "Can't create LauncherItems in QML. Get them from the LauncherModel");
45+}
tests/mocks/Unity/Launcher/plugin.hnew file+35
@@ -0,0 +1,35 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Michael Zanetti <michael.zanetti@canonical.com>
18+ */
19+
20+
21+#ifndef TESTLAUNCHER_PLUGIN_H
22+#define TESTLAUNCHER_PLUGIN_H
23+
24+#include <QtQml/QQmlExtensionPlugin>
25+
26+class TestLauncherPlugin : public QQmlExtensionPlugin
27+{
28+ Q_OBJECT
29+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
30+
31+public:
32+ void registerTypes(const char* uri);
33+};
34+
35+#endif // TESTLAUNCHER_PLUGIN_H
tests/mocks/Unity/Launcher/qmldirnew file+2
@@ -0,0 +1,2 @@
1+module Unity.Launcher
2+plugin MockLauncherPlugin
tests/mocks/Unity/fake_categories.cppnew file+178
@@ -0,0 +1,178 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Author: Nick Dedekind <nick.dedekind@canonical.com>
17+ */
18+
19+// self
20+#include "fake_categories.h"
21+
22+// local
23+#include "categoryresults.h"
24+
25+#define CATEGORY_COLUMN 2
26+
27+Categories::Categories(QObject* parent)
28+ : DeeListModel(parent)
29+{
30+ // FIXME: need to clean up unused filters on countChanged
31+ m_roles[Categories::RoleId] = "id";
32+ m_roles[Categories::RoleName] = "name";
33+ m_roles[Categories::RoleIcon] = "icon";
34+ m_roles[Categories::RoleRenderer] = "renderer";
35+ m_roles[Categories::RoleContentType] = "content_type";
36+ m_roles[Categories::RoleHints] = "hints";
37+ m_roles[Categories::RoleResults] = "results";
38+ m_roles[Categories::RoleCount] = "count";
39+
40+ // TODO This should not be needed but accumulatting the count changes
41+ // makes the visualization more stable and also makes crashes on fast
42+ // change of the search term harder to reproduce
43+ m_timer.setSingleShot(true);
44+ m_timer.setInterval(50);
45+ connect(&m_timer, SIGNAL(timeout()), this, SLOT(onEmitCountChanged()));
46+}
47+
48+DeeListModel*
49+Categories::getFilter(int index) const
50+{
51+ if (!m_filters.contains(index)) {
52+ auto results = new CategoryResults ();
53+ results->setCategoryIndex(index);
54+ connect(results, SIGNAL(countChanged()), this, SLOT(onCountChanged()));
55+
56+ unsigned cat_index = static_cast<unsigned>(index);
57+ auto model = getResultsForCategory(cat_index);
58+ results->setModel(model);
59+
60+ m_filters.insert(index, results);
61+ }
62+
63+ return m_filters[index];
64+}
65+
66+void
67+Categories::onCountChanged()
68+{
69+ DeeListModel* filter = qobject_cast<DeeListModel*>(sender());
70+ if (filter) {
71+ m_timerFilters << filter;
72+ m_timer.start();
73+ }
74+}
75+
76+void
77+Categories::onEmitCountChanged()
78+{
79+ QVector<int> roles;
80+ roles.append(Categories::RoleCount);
81+ Q_FOREACH(DeeListModel* results, m_timerFilters) {
82+ auto cat_results = qobject_cast<CategoryResults*>(results);
83+ QModelIndex changedIndex = index(cat_results->categoryIndex());
84+ Q_EMIT dataChanged(changedIndex, changedIndex, roles);
85+ }
86+ m_timerFilters.clear();
87+}
88+
89+QHash<int, QByteArray>
90+Categories::roleNames() const
91+{
92+ return m_roles;
93+}
94+
95+void Categories::setResultModel(DeeModel* model)
96+{
97+ // FIXME: should ref it
98+ m_dee_results = model;
99+}
100+
101+
102+static void category_filter_map_func (DeeModel* orig_model,
103+ DeeFilterModel* filter_model,
104+ gpointer user_data)
105+{
106+ DeeModelIter* iter;
107+ DeeModelIter* end;
108+ unsigned index = GPOINTER_TO_UINT(user_data);
109+
110+ iter = dee_model_get_first_iter(orig_model);
111+ end = dee_model_get_last_iter(orig_model);
112+ while (iter != end) {
113+ unsigned category_index = dee_model_get_uint32(orig_model, iter, CATEGORY_COLUMN);
114+ if (index == category_index) {
115+ dee_filter_model_append_iter(filter_model, iter);
116+ }
117+ iter = dee_model_next(orig_model, iter);
118+ }
119+}
120+
121+static gboolean category_filter_notify_func (DeeModel* orig_model,
122+ DeeModelIter* orig_iter,
123+ DeeFilterModel* filter_model,
124+ gpointer user_data)
125+{
126+ unsigned index = GPOINTER_TO_UINT(user_data);
127+ unsigned category_index = dee_model_get_uint32(orig_model, orig_iter, CATEGORY_COLUMN);
128+
129+ if (index != category_index)
130+ return FALSE;
131+
132+ dee_filter_model_insert_iter_with_original_order(filter_model, orig_iter);
133+ return TRUE;
134+}
135+
136+DeeModel* Categories::getResultsForCategory(unsigned cat_index) const
137+{
138+ DeeFilter filter;
139+ filter.map_func = category_filter_map_func;
140+ filter.map_notify = category_filter_notify_func;
141+ filter.destroy = nullptr;
142+ filter.userdata = GUINT_TO_POINTER(cat_index);
143+
144+ DeeModel* filtered_model = dee_filter_model_new(m_dee_results, &filter);
145+ return filtered_model;
146+}
147+
148+QVariant
149+Categories::data(const QModelIndex& index, int role) const
150+{
151+ if (!index.isValid()) {
152+ return QVariant();
153+ }
154+
155+ switch (role) {
156+ case RoleId:
157+ return QVariant::fromValue(index.row());
158+ case RoleName:
159+ return DeeListModel::data(index, 1); //DISPLAY_NAME
160+ case RoleIcon:
161+ return DeeListModel::data(index, 2); //ICON_HINT
162+ case RoleRenderer:
163+ return DeeListModel::data(index, 3); //RENDERER_NAME
164+ case RoleContentType:
165+ {
166+ auto hints = DeeListModel::data(index, 4).toHash();
167+ return hints.contains("content-type") ? hints["content-type"] : QVariant(QString("default"));
168+ }
169+ case RoleHints:
170+ return DeeListModel::data(index, 4); //HINTS
171+ case RoleResults:
172+ return QVariant::fromValue(getFilter(index.row()));
173+ case RoleCount:
174+ return QVariant::fromValue(getFilter(index.row())->rowCount());
175+ default:
176+ return QVariant();
177+ }
178+}
tests/mocks/Unity/fake_categories.hnew file+69
@@ -0,0 +1,69 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef FAKE_CATEGORIES_H
18+#define FAKE_CATEGORIES_H
19+
20+// Qt
21+#include <QObject>
22+#include <QSet>
23+#include <QTimer>
24+
25+#include <dee.h>
26+#include <deelistmodel.h>
27+
28+class Categories : public DeeListModel
29+{
30+ Q_OBJECT
31+
32+ Q_ENUMS(Roles)
33+
34+public:
35+ Categories(QObject* parent = 0);
36+ enum Roles {
37+ RoleId,
38+ RoleName,
39+ RoleIcon,
40+ RoleRenderer,
41+ RoleContentType,
42+ RoleHints,
43+ RoleResults,
44+ RoleCount
45+ };
46+
47+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
48+
49+ QHash<int, QByteArray> roleNames() const;
50+
51+ /* setters */
52+ void setResultModel(DeeModel* model);
53+
54+private Q_SLOTS:
55+ void onCountChanged();
56+ void onEmitCountChanged();
57+
58+private:
59+ DeeModel* getResultsForCategory(unsigned index) const;
60+ DeeListModel* getFilter(int index) const;
61+
62+ DeeModel* m_dee_results;
63+ QTimer m_timer;
64+ QSet<DeeListModel*> m_timerFilters;
65+ QHash<int, QByteArray> m_roles;
66+ mutable QMap<int, DeeListModel*> m_filters;
67+};
68+
69+#endif // FAKE_CATEGORIES_H
tests/mocks/Unity/fake_launchermodel.cppdeleted−150
@@ -1,150 +0,0 @@
1−/*
2− * Copyright (C) 2011 Canonical, Ltd.
3− *
4− * Authors:
5− * Michael Zanetti <michael.zanetti@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 "launchermodel.h"
21−
22−LauncherModel::LauncherModel(QObject *parent): QAbstractListModel(parent)
23−{
24− LauncherItem *item = new LauncherItem("/usr/share/applications/phone-app.desktop", "Phone", "phone-app");
25− m_list.append(item);
26− item = new LauncherItem("/usr/share/applications/camera-app.desktop", "Camera", "camera");
27− m_list.append(item);
28− item = new LauncherItem("/usr/share/applications/gallery-app.desktop", "Gallery", "gallery");
29− m_list.append(item);
30− item = new LauncherItem("/usr/share/applications/facebook-webapp.desktop", "Facebook", "facebook");
31− m_list.append(item);
32− item = new LauncherItem("/usr/share/applications/webbrowser-app.desktop", "Browser", "browser");
33− m_list.append(item);
34− item = new LauncherItem("/usr/share/applications/twitter-webapp.desktop", "Twitter", "twitter");
35− m_list.append(item);
36− item = new LauncherItem("/usr/share/applications/gmail-webapp.desktop", "GMail", "gmail");
37− m_list.append(item);
38− item = new LauncherItem("/usr/share/applications/ubuntu-weather-app.desktop", "Weather", "weather");
39− m_list.append(item);
40− item = new LauncherItem("/usr/share/applications/notes-app.desktop", "Notepad", "notepad");
41− m_list.append(item);
42− item = new LauncherItem("/usr/share/applications/ubuntu-calendar-app.desktop","Calendar", "calendar");
43− m_list.append(item);
44−}
45−
46−LauncherModel::~LauncherModel()
47−{
48− while (!m_list.empty()) {
49− m_list.takeFirst()->deleteLater();
50− }
51−}
52−
53−int LauncherModel::rowCount(const QModelIndex &parent) const
54−{
55− Q_UNUSED(parent)
56− return m_list.count();
57−}
58−
59−QVariant LauncherModel::data(const QModelIndex &index, int role) const
60−{
61− LauncherItem *item = m_list.at(index.row());
62− switch(role) {
63− case RoleName:
64− return item->name();
65− case RoleIcon:
66− return item->icon();
67− case RoleFavorite:
68− return item->favorite();
69− }
70−
71− return QVariant();
72−}
73−
74−LauncherItem *LauncherModel::get(int index) const
75−{
76− if (index < 0 || index >= m_list.count()) {
77− return 0;
78− }
79− return m_list.at(index);
80−}
81−
82−void LauncherModel::move(int oldIndex, int newIndex)
83−{
84− beginMoveRows(QModelIndex(), oldIndex, oldIndex, QModelIndex(), newIndex);
85− m_list.move(oldIndex, newIndex);
86− endMoveRows();
87−}
88−
89−QHash<int, QByteArray> LauncherModel::roleNames() const
90−{
91− QHash<int, QByteArray> roles;
92− roles.insert(RoleDesktopFile, "desktopFile");
93− roles.insert(RoleName, "name");
94− roles.insert(RoleIcon, "icon");
95− roles.insert(RoleFavorite, "favorite");
96− roles.insert(RoleRunning, "runnng");
97− return roles;
98−}
99−
100−
101−LauncherItem::LauncherItem(const QString &desktopFile, const QString &name, const QString &icon, QObject *parent):
102− QObject(parent),
103− m_desktopFile(desktopFile),
104− m_name(name),
105− m_icon(icon),
106− m_favorite(false)
107−{
108−
109−}
110−
111−QString LauncherItem::desktopFile() const
112−{
113− return m_desktopFile;
114−}
115−
116−QString LauncherItem::name() const
117−{
118− return m_name;
119−}
120−
121−QString LauncherItem::icon() const
122−{
123− return m_icon;
124−}
125−
126−bool LauncherItem::favorite() const
127−{
128− return m_favorite;
129−}
130−
131−void LauncherItem::setFavorite(bool favorite)
132−{
133− if (m_favorite != favorite) {
134− m_favorite = favorite;
135− Q_EMIT favoriteChanged(m_favorite);
136− }
137−}
138−
139−bool LauncherItem::running() const
140−{
141− return m_running;
142−}
143−
144−void LauncherItem::setRunning(bool running)
145−{
146− if (m_running != running) {
147− m_running = running;
148− Q_EMIT runningChanged(running);
149− }
150−}
tests/mocks/Unity/fake_launchermodel.hdeleted−86
@@ -1,86 +0,0 @@
1−/*
2− * Copyright (C) 2011 Canonical, Ltd.
3− *
4− * Authors:
5− * Michael Zanetti <michael.zanetti@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 <QAbstractListModel>
21−
22−class LauncherItem;
23−
24−class LauncherModel: public QAbstractListModel
25−{
26− Q_OBJECT
27−
28−public:
29− enum Roles {
30− RoleDesktopFile = Qt::UserRole,
31− RoleName,
32− RoleIcon,
33− RoleFavorite,
34− RoleRunning
35− };
36−
37− LauncherModel(QObject *parent = 0);
38− ~LauncherModel();
39−
40− int rowCount(const QModelIndex &parent) const;
41−
42− QVariant data(const QModelIndex &index, int role) const;
43−
44− Q_INVOKABLE LauncherItem* get(int index) const;
45− Q_INVOKABLE void move(int oldIndex, int newIndex);
46−
47− QHash<int, QByteArray> roleNames() const;
48−
49−private:
50− QList<LauncherItem*> m_list;
51−};
52−
53−class LauncherItem: public QObject
54−{
55− Q_OBJECT
56− Q_PROPERTY(QString desktopFile READ desktopFile CONSTANT)
57− Q_PROPERTY(QString name READ name CONSTANT)
58− Q_PROPERTY(QString icon READ icon CONSTANT)
59− Q_PROPERTY(bool favorite READ favorite WRITE setFavorite NOTIFY favoriteChanged)
60− Q_PROPERTY(bool running READ running WRITE setRunning NOTIFY runningChanged)
61−
62−public:
63− LauncherItem(const QString &desktopFile, const QString &name, const QString &icon, QObject *parent = 0);
64−
65− QString desktopFile() const;
66−
67− QString name() const;
68− QString icon() const;
69−
70− bool favorite() const;
71− void setFavorite(bool favorite);
72−
73− bool running() const;
74− void setRunning(bool running);
75−
76−Q_SIGNALS:
77− void favoriteChanged(bool favorite);
78− void runningChanged(bool running);
79−
80−private:
81− QString m_desktopFile;
82− QString m_name;
83− QString m_icon;
84− bool m_favorite;
85− bool m_running;
86−};
tests/mocks/Unity/fake_scope.cpp+104−73
@@ -26,32 +26,29 @@ static DeeModel* create_results_model(unsigned category_count, unsigned result_c
26// TODO: Implement remaining pieces
26// TODO: Implement remaining pieces
27
27
28Scope::Scope(QObject* parent)
28Scope::Scope(QObject* parent)
29−: QObject(parent),
29+ : QObject(parent)
30− m_visible(false),
30+ , m_visible(false)
31− m_categories(new Categories(this)),
31+ , m_categories(new Categories(this))
32− m_results(new DeeListModel(this))
32+ , m_results(new DeeListModel(this))
33{
33{
34+ DeeModel* results_model = create_results_model(4, 30);
35+ m_categories->setResultModel(results_model);
34 m_categories->setModel(create_categories_model(4));
36 m_categories->setModel(create_categories_model(4));
35− m_results->setModel(create_results_model(4, 30));
37+ m_results->setModel(results_model);
36−
37− m_categories->setResultModel(m_results);
38}
38}
39
39
40−Scope::Scope(QString const& id,
40+Scope::Scope(QString const& id, QString const& name, bool visible, QObject* parent)
41− QString const& name,
42− bool visible,
43− QObject* parent)
44−: QObject(parent),
41+ : QObject(parent)
45− m_id(id),
42+ , m_id(id)
46− m_name(name),
43+ , m_name(name)
47− m_visible(visible),
44+ , m_visible(visible)
48− m_categories(new Categories(this)),
45+ , m_categories(new Categories(this))
49− m_results(new DeeListModel(this))
46+ , m_results(new DeeListModel(this))
50{
47{
48+ DeeModel* results_model = create_results_model(4, 30);
49+ m_categories->setResultModel(results_model);
51 m_categories->setModel(create_categories_model(4));
50 m_categories->setModel(create_categories_model(4));
52− m_results->setModel(create_results_model(4, 30));
51+ m_results->setModel(results_model);
53−
54− m_categories->setResultModel(m_results);
55}
52}
56
53
57QString Scope::id() const {
54QString Scope::id() const {
@@ -66,6 +63,42 @@ QString Scope::searchQuery() const {
66 return m_searchQuery;
63 return m_searchQuery;
67}
64}
68
65
66+QString Scope::iconHint() const {
67+ return m_iconHint;
68+}
69+
70+QString Scope::description() const {
71+ return m_description;
72+}
73+
74+QString Scope::searchHint() const {
75+ return QString("");
76+}
77+
78+QString Scope::shortcut() const {
79+ return QString("");
80+}
81+
82+bool Scope::connected() const {
83+ return true;
84+}
85+
86+Categories* Scope::categories() const {
87+ return m_categories;
88+}
89+
90+QString Scope::noResultsHint() const {
91+ return m_noResultsHint;
92+}
93+
94+QString Scope::formFactor() const {
95+ return m_formFactor;
96+}
97+
98+bool Scope::visible() const {
99+ return m_visible;
100+}
101+
69void Scope::setName(const QString &str) {
102void Scope::setName(const QString &str) {
70 if (str != m_name) {
103 if (str != m_name) {
71 m_name = str;
104 m_name = str;
@@ -76,45 +109,47 @@ void Scope::setName(const QString &str) {
76void Scope::setSearchQuery(const QString &str) {
109void Scope::setSearchQuery(const QString &str) {
77 if (str != m_searchQuery) {
110 if (str != m_searchQuery) {
78 m_searchQuery = str;
111 m_searchQuery = str;
79− Q_EMIT searchQueryChanged(m_searchQuery);
112+ Q_EMIT searchQueryChanged();
80 }
113 }
81}
114}
82
115
83−bool Scope::visible() const {
116+void Scope::setFormFactor(const QString &str) {
84− return m_visible;
117+ if (str != m_formFactor) {
118+ m_formFactor = str;
119+ Q_EMIT formFactorChanged();
120+ }
85}
121}
86
122
87−Categories* Scope::categories() const {
123+void Scope::setNoResultsHint(const QString& str) {
88− return m_categories;
124+ if (str != m_noResultsHint) {
125+ m_noResultsHint = str;
126+ Q_EMIT noResultsHintChanged();
127+ }
89}
128}
90
129
91static const gchar * categories_model_schema[] = {
130static const gchar * categories_model_schema[] = {
92− "s", //ID
131+ "s", //ID
93− "s", // DISPLAY_NAME
132+ "s", // DISPLAY_NAME
94− "s", // ICON_HINT
133+ "s", // ICON_HINT
95− "s", // RENDERER_NAME
134+ "s", // RENDERER_NAME
96− "a{sv}" // HINTS
135+ "a{sv}" // HINTS
97};
136};
98
137
99
138
100DeeModel* create_categories_model(unsigned category_count) {
139DeeModel* create_categories_model(unsigned category_count) {
101 DeeModel* category_model = dee_sequence_model_new();
140 DeeModel* category_model = dee_sequence_model_new();
102 dee_model_set_schema_full(category_model, categories_model_schema, G_N_ELEMENTS(categories_model_schema));
141 dee_model_set_schema_full(category_model, categories_model_schema, G_N_ELEMENTS(categories_model_schema));
103−
142+ GVariant* hints = g_variant_new_array(g_variant_type_element(G_VARIANT_TYPE_VARDICT), NULL, 0);
104− GVariantBuilder b;
105− g_variant_builder_init(&b, G_VARIANT_TYPE("a{sv}"));
106− GVariant *hints = g_variant_builder_end(&b);
107
143
108 for(unsigned i = 0; i < category_count; ++i)
144 for(unsigned i = 0; i < category_count; ++i)
109 {
145 {
110− dee_model_append(category_model,
146+ dee_model_append(category_model,
111− std::to_string(i).c_str(),
147+ std::to_string(i).c_str(),
112− ("Category "+std::to_string(i)).c_str(),
148+ ("Category "+std::to_string(i)).c_str(),
113− "gtk-apply",
149+ "gtk-apply",
114− "grid",
150+ "grid",
115− hints);
151+ hints);
116 }
152 }
117− g_variant_unref(hints);
118 return category_model;
153 return category_model;
119}
154}
120
155
@@ -122,48 +157,44 @@ DeeModel* create_categories_model(unsigned category_count) {
122/* Schema that is used in the DeeModel representing
157/* Schema that is used in the DeeModel representing
123 the results */
158 the results */
124static const gchar * results_model_schema[] = {
159static const gchar * results_model_schema[] = {
125− "s", // URI
160+ "s", // URI
126− "s", // ICON_HINT
161+ "s", // ICON_HINT
127− "u", // CATEGORY
162+ "u", // CATEGORY
128− "u", // RESULT_TYPE
163+ "u", // RESULT_TYPE
129− "s", // MIMETYPE
164+ "s", // MIMETYPE
130− "s", // TITLE
165+ "s", // TITLE
131− "s", // COMMENT
166+ "s", // COMMENT
132− "s", // DND_URI
167+ "s", // DND_URI
133− "a{sv}" // METADATA
168+ "a{sv}" // METADATA
134};
169};
135
170
136static const gchar * icons[] = {
171static const gchar * icons[] = {
137− "Applications.png",
172+ "Applications.png",
138− "Home.png",
173+ "Home.png",
139− "Music.png",
174+ "Music.png",
140− "People.png",
175+ "People.png",
141− "Videos.png",
176+ "Videos.png",
142};
177};
143
178
144DeeModel* create_results_model(unsigned category_count, unsigned result_count) {
179DeeModel* create_results_model(unsigned category_count, unsigned result_count) {
145 DeeModel* results_model = dee_sequence_model_new();
180 DeeModel* results_model = dee_sequence_model_new();
146 dee_model_set_schema_full(results_model, results_model_schema, G_N_ELEMENTS(results_model_schema));
181 dee_model_set_schema_full(results_model, results_model_schema, G_N_ELEMENTS(results_model_schema));
147−
182+ GVariant* hints = g_variant_new_array(g_variant_type_element(G_VARIANT_TYPE_VARDICT), NULL, 0);
148− GVariantBuilder b;
149− g_variant_builder_init(&b, G_VARIANT_TYPE("a{sv}"));
150− GVariant *hints = g_variant_builder_end(&b);
151
183
152 for(unsigned i = 0; i < result_count; ++i)
184 for(unsigned i = 0; i < result_count; ++i)
153 {
185 {
154− unsigned category = i % category_count;
186+ unsigned category = i % category_count;
155−
187+
156− dee_model_append(results_model,
188+ dee_model_append(results_model,
157− ("uri://result."+std::to_string(i)).c_str(),
189+ ("uri://result."+std::to_string(i)).c_str(),
158− (shellAppDirectory() + "Dash/graphics/scopeIcons/" + (icons[i%G_N_ELEMENTS(icons)])).toLatin1().data(),
190+ (shellAppDirectory() + "Dash/graphics/scopeIcons/" + (icons[i%G_N_ELEMENTS(icons)])).toLatin1().data(),
159− category,
191+ category,
160− 0,
192+ 0,
161− "application/x-desktop",
193+ "application/x-desktop",
162− ("Title."+std::to_string(i)).c_str(),
194+ ("Title."+std::to_string(i)).c_str(),
163− ("Comment."+std::to_string(i)).c_str(),
195+ ("Comment."+std::to_string(i)).c_str(),
164− ("uri://result."+std::to_string(i)).c_str(),
196+ ("uri://result."+std::to_string(i)).c_str(),
165− hints);
197+ hints);
166 }
198 }
167− g_variant_unref(hints);
168 return results_model;
199 return results_model;
169− }
200+}
tests/mocks/Unity/fake_scope.h+43−11
@@ -19,43 +19,75 @@
19
19
20// Qt
20// Qt
21#include <QObject>
21#include <QObject>
22−#include "categories.h"
22+#include "fake_categories.h"
23
23
24class Scope : public QObject
24class Scope : public QObject
25{
25{
26 Q_OBJECT
26 Q_OBJECT
27+
27 Q_PROPERTY(QString id READ id NOTIFY idChanged)
28 Q_PROPERTY(QString id READ id NOTIFY idChanged)
28− Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
29+ Q_PROPERTY(QString name READ name NOTIFY nameChanged)
29− Q_PROPERTY(QString searchQuery READ searchQuery WRITE setSearchQuery NOTIFY searchQueryChanged)
30+ Q_PROPERTY(QString iconHint READ iconHint NOTIFY iconHintChanged)
31+ Q_PROPERTY(QString description READ description NOTIFY descriptionChanged)
32+ Q_PROPERTY(QString searchHint READ searchHint NOTIFY searchHintChanged)
30 Q_PROPERTY(bool visible READ visible NOTIFY visibleChanged)
33 Q_PROPERTY(bool visible READ visible NOTIFY visibleChanged)
34+ Q_PROPERTY(QString shortcut READ shortcut NOTIFY shortcutChanged)
35+ Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged)
31 Q_PROPERTY(Categories* categories READ categories NOTIFY categoriesChanged)
36 Q_PROPERTY(Categories* categories READ categories NOTIFY categoriesChanged)
32
37
38+ Q_PROPERTY(QString searchQuery READ searchQuery WRITE setSearchQuery NOTIFY searchQueryChanged)
39+ Q_PROPERTY(QString noResultsHint READ noResultsHint WRITE setNoResultsHint NOTIFY noResultsHintChanged)
40+ Q_PROPERTY(QString formFactor READ formFactor WRITE setFormFactor NOTIFY formFactorChanged)
41+
33public:
42public:
34 Scope(QObject* parent = 0);
43 Scope(QObject* parent = 0);
35 Scope(QString const& id, QString const& name, bool visible, QObject* parent = 0);
44 Scope(QString const& id, QString const& name, bool visible, QObject* parent = 0);
36
45
46+ /* getters */
37 QString id() const;
47 QString id() const;
38 QString name() const;
48 QString name() const;
39− QString searchQuery() const;
49+ QString iconHint() const;
50+ QString description() const;
51+ QString searchHint() const;
40 bool visible() const;
52 bool visible() const;
41−
53+ QString shortcut() const;
42− void setName(const QString &str);
54+ bool connected() const;
43− void setSearchQuery(const QString &str);
44−
45 Categories* categories() const;
55 Categories* categories() const;
56+ QString searchQuery() const;
57+ QString noResultsHint() const;
58+ QString formFactor() const;
59+
60+ /* setters */
61+ void setName(const QString& name);
62+ void setSearchQuery(const QString& search_query);
63+ void setNoResultsHint(const QString& hint);
64+ void setFormFactor(const QString& form_factor);
46
65
47Q_SIGNALS:
66Q_SIGNALS:
48− void idChanged(QString);
67+ void idChanged(const QString&);
49− void nameChanged(QString);
68+ void nameChanged(const QString&);
50− void searchQueryChanged(QString);
69+ void iconHintChanged(const QString&);
70+ void descriptionChanged(const QString&);
71+ void searchHintChanged(const QString&);
51 void visibleChanged(bool);
72 void visibleChanged(bool);
73+ void shortcutChanged(const QString&);
74+ void connectedChanged(bool);
52 void categoriesChanged();
75 void categoriesChanged();
76+ void searchFinished(const QString&);
77+ void searchQueryChanged();
78+ void noResultsHintChanged();
79+ void formFactorChanged();
53
80
54private:
81private:
55 QString m_id;
82 QString m_id;
83+ QString m_iconHint;
84+ QString m_description;
56 QString m_name;
85 QString m_name;
57 QString m_searchQuery;
86 QString m_searchQuery;
87+ QString m_noResultsHint;
88+ QString m_formFactor;
58 bool m_visible;
89 bool m_visible;
90+
59 Categories* m_categories;
91 Categories* m_categories;
60 DeeListModel* m_results;
92 DeeListModel* m_results;
61};
93};
tests/mocks/Unity/fake_unity_plugin.cpp+3−6
@@ -21,9 +21,8 @@
21
21
22// local
22// local
23#include "fake_scopes.h"
23#include "fake_scopes.h"
24−#include "categories.h"
24+#include "fake_categories.h"
25−#include "categoryfilter.h"
25+#include "categoryresults.h"
26−#include "fake_launchermodel.h"
27
26
28// External
27// External
29#include <glib-object.h>
28#include <glib-object.h>
@@ -40,7 +39,5 @@ void FakeUnityPlugin::registerTypes(const char *uri)
40 qmlRegisterType<Scopes>(uri, 0, 1, "Scopes");
39 qmlRegisterType<Scopes>(uri, 0, 1, "Scopes");
41 qmlRegisterType<Scope>(uri, 0, 1, "Scope");
40 qmlRegisterType<Scope>(uri, 0, 1, "Scope");
42 qmlRegisterType<Categories>(uri, 0, 1, "Categories");
41 qmlRegisterType<Categories>(uri, 0, 1, "Categories");
43− qmlRegisterType<CategoryFilter>(uri, 0, 1, "CategoryFilter");
44− qmlRegisterType<LauncherModel>(uri, 0, 1, "LauncherModel");
45− qmlRegisterUncreatableType<LauncherItem>(uri, 0, 1, "LauncherItem", "Can't create");
42+ qmlRegisterUncreatableType<CategoryResults>(uri, 0, 1, "CategoryResults", "Can't create");
46}
43}
tests/plugins/ListViewWithPageHeader/listviewwithpageheadertest.cpp+58
@@ -20,9 +20,12 @@
20#include <QQmlEngine>
20#include <QQmlEngine>
21#include <QQuickView>
21#include <QQuickView>
22#include <QtTestGui>
22#include <QtTestGui>
23+#pragma GCC diagnostic push
24+#pragma GCC diagnostic ignored "-pedantic"
23#include <private/qquicklistmodel_p.h>
25#include <private/qquicklistmodel_p.h>
24#include <private/qquickanimation_p.h>
26#include <private/qquickanimation_p.h>
25#include <private/qquickitem_p.h>
27#include <private/qquickitem_p.h>
28+#pragma GCC diagnostic pop
26
29
27class ListViewWithPageHeaderTest : public QObject
30class ListViewWithPageHeaderTest : public QObject
28{
31{
@@ -1248,6 +1251,61 @@ private Q_SLOTS:
1248 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1251 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1249 }
1252 }
1250
1253
1254+ void testShowHeaderHalfShown()
1255+ {
1256+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
1257+ QSKIP("This test is extremely unstable in 5.0.x");
1258+#endif
1259+ changeContentY(20);
1260+
1261+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
1262+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1263+ verifyItem(0, 30., 150., false);
1264+ verifyItem(1, 180, 200., false);
1265+ verifyItem(2, 380, 350., false);
1266+ verifyItem(3, 730, 350., true);
1267+ QCOMPARE(lvwph->m_minYExtent, 0.);
1268+ QCOMPARE(lvwph->m_clipItem->y(), 20.);
1269+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1270+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1271+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1272+ QCOMPARE(lvwph->contentY(), 20.);
1273+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);;
1274+
1275+ lvwph->showHeader();
1276+
1277+ QTRY_VERIFY(!lvwph->m_headerShowAnimation->isRunning());
1278+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
1279+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1280+ verifyItem(0, -20., 150., false);
1281+ verifyItem(1, 130, 200., false);
1282+ verifyItem(2, 330, 350., false);
1283+ verifyItem(3, 680, 350., true);
1284+ QCOMPARE(lvwph->m_minYExtent, 20.);
1285+ QCOMPARE(lvwph->m_clipItem->y(), 50.);
1286+ QCOMPARE(lvwph->m_clipItem->clip(), true);
1287+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1288+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1289+ QCOMPARE(lvwph->contentY(), 0.);
1290+ QCOMPARE(lvwph->m_headerItemShownHeight, 50.);
1291+
1292+ scrollToTop();
1293+
1294+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 4);
1295+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1296+ verifyItem(0, 50., 150., false);
1297+ verifyItem(1, 200., 200., false);
1298+ verifyItem(2, 400., 350., false);
1299+ verifyItem(3, 750, 350., true);
1300+ QCOMPARE(lvwph->m_minYExtent, 20.);
1301+ QCOMPARE(lvwph->m_clipItem->y(), -20.);
1302+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1303+ QCOMPARE(lvwph->m_headerItem->y(), -20.);
1304+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1305+ QCOMPARE(lvwph->contentY(), -20.);
1306+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1307+ }
1308+
1251 void testShowHeaderAtBottom()
1309 void testShowHeaderAtBottom()
1252 {
1310 {
1253 scrollToBottom();
1311 scrollToBottom();
tests/plugins/ListViewWithPageHeader/listviewwithpageheadertestsection.cpp+60
@@ -20,9 +20,12 @@
20#include <QQmlEngine>
20#include <QQmlEngine>
21#include <QQuickView>
21#include <QQuickView>
22#include <QtTestGui>
22#include <QtTestGui>
23+#pragma GCC diagnostic push
24+#pragma GCC diagnostic ignored "-pedantic"
23#include <private/qquicklistmodel_p.h>
25#include <private/qquicklistmodel_p.h>
24#include <private/qquickanimation_p.h>
26#include <private/qquickanimation_p.h>
25#include <private/qquickitem_p.h>
27#include <private/qquickitem_p.h>
28+#pragma GCC diagnostic pop
26
29
27class ListViewWithPageHeaderTestSection : public QObject
30class ListViewWithPageHeaderTestSection : public QObject
28{
31{
@@ -1407,6 +1410,63 @@ private Q_SLOTS:
1407 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1410 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1408 }
1411 }
1409
1412
1413+ void testShowHeaderHalfShown()
1414+ {
1415+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
1416+ QSKIP("This test is extremely unstable in 5.0.x");
1417+#endif
1418+ changeContentY(20);
1419+
1420+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
1421+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1422+ verifyItem(0, 30., 190., false, "Agressive", false);
1423+ verifyItem(1, 220, 240., false, "Regular", false);
1424+ verifyItem(2, 460, 390., false, "Mild", false);
1425+ QCOMPARE(lvwph->m_minYExtent, 0.);
1426+ QCOMPARE(lvwph->m_clipItem->y(), 20.);
1427+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1428+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1429+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1430+ QCOMPARE(lvwph->contentY(), 20.);
1431+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);;
1432+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1433+
1434+ lvwph->showHeader();
1435+
1436+ QTRY_VERIFY(!lvwph->m_headerShowAnimation->isRunning());
1437+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
1438+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1439+ verifyItem(0, -20., 190., false, "Agressive", true);
1440+ verifyItem(1, 170, 240., false, "Regular", false);
1441+ verifyItem(2, 410, 390., false, "Mild", false);
1442+ QCOMPARE(lvwph->m_minYExtent, 20.);
1443+ QCOMPARE(lvwph->m_clipItem->y(), 50.);
1444+ QCOMPARE(lvwph->m_clipItem->clip(), true);
1445+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1446+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1447+ QCOMPARE(lvwph->contentY(), 0.);
1448+ QCOMPARE(lvwph->m_headerItemShownHeight, 50.);
1449+ QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1450+ QCOMPARE(section(lvwph->m_topSectionItem), QString("Agressive"));
1451+ QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1452+
1453+ scrollToTop();
1454+
1455+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
1456+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1457+ verifyItem(0, 50., 190., false, "Agressive", false);
1458+ verifyItem(1, 240., 240., false, "Regular", false);
1459+ verifyItem(2, 480., 390., false, "Mild", false);
1460+ QCOMPARE(lvwph->m_minYExtent, 20.);
1461+ QCOMPARE(lvwph->m_clipItem->y(), -20.);
1462+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1463+ QCOMPARE(lvwph->m_headerItem->y(), -20.);
1464+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1465+ QCOMPARE(lvwph->contentY(), -20.);
1466+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1467+ QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1468+ }
1469+
1410 void testShowHeaderCloseToTheTop()
1470 void testShowHeaderCloseToTheTop()
1411 {
1471 {
1412 changeContentY(375);
1472 changeContentY(375);
tests/plugins/Unity/CMakeLists.txt+1−1
@@ -23,7 +23,7 @@ macro(run_tests)
23 add_executable(${_test}Exec ${_test}.cpp previewbindingstest.cpp)
23 add_executable(${_test}Exec ${_test}.cpp previewbindingstest.cpp)
24 qt5_use_modules(${_test}Exec Test Core Qml)
24 qt5_use_modules(${_test}Exec Test Core Qml)
25 set_tests_properties(test${CLASSNAME}${_test}
25 set_tests_properties(test${CLASSNAME}${_test}
26− PROPERTIES ENVIRONMENT LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/plugins/Unity:${LIBUNITYPROTO_LIBRARY_DIRS})
26+ PROPERTIES ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/plugins/Unity:${LIBUNITYPROTO_LIBRARY_DIRS}")
27
27
28 target_link_libraries(${_test}Exec
28 target_link_libraries(${_test}Exec
29 Unity-qml
29 Unity-qml
tests/plugins/Unity/previewbindingstest.cpp+113−58
@@ -25,6 +25,12 @@
25#include "applicationpreview.h"
25#include "applicationpreview.h"
26#include "moviepreview.h"
26#include "moviepreview.h"
27#include "musicpreview.h"
27#include "musicpreview.h"
28+#include "socialpreview.h"
29+#include "socialpreviewcomment.h"
30+#include "previewaction.h"
31+
32+#include <glib.h>
33+#include <glib-object.h>
28
34
29void PreviewBindingsTest::initTestCase()
35void PreviewBindingsTest::initTestCase()
30{
36{
@@ -32,81 +38,130 @@ void PreviewBindingsTest::initTestCase()
32
38
33void PreviewBindingsTest::testGenericPreview()
39void PreviewBindingsTest::testGenericPreview()
34{
40{
35− auto raw_preview = (GObject *)unity_protocol_generic_preview_new();
41+ auto rawPreview = (GObject *)unity_protocol_generic_preview_new();
36− unity_protocol_preview_set_title(UNITY_PROTOCOL_PREVIEW(raw_preview), "Metallica");
42+ unity_protocol_preview_set_title(UNITY_PROTOCOL_PREVIEW(rawPreview), "Metallica");
37− unity_protocol_preview_set_subtitle(UNITY_PROTOCOL_PREVIEW(raw_preview), "Ride The Lightning");
43+ unity_protocol_preview_set_subtitle(UNITY_PROTOCOL_PREVIEW(rawPreview), "Ride The Lightning");
38− unity_protocol_preview_set_description(UNITY_PROTOCOL_PREVIEW(raw_preview), "Lorem ipsum dolor sit amet");
44+ unity_protocol_preview_set_description(UNITY_PROTOCOL_PREVIEW(rawPreview), "Lorem ipsum dolor sit amet");
45+ GFile *iconFile = g_file_new_for_path("/foo.png");
46+ GIcon *icon = g_file_icon_new(iconFile);
47+ unity_protocol_preview_add_action(UNITY_PROTOCOL_PREVIEW(rawPreview), "1", "Action1", icon,
48+ UNITY_PROTOCOL_LAYOUT_HINT_LEFT);
39− unity::glib::Object<GObject> gen_prv(raw_preview);
49+ unity::glib::Object<GObject> genPrv(rawPreview);
40−
50+
41− auto core_prv = unity::dash::Preview::PreviewForProtocolObject(gen_prv);
51+ auto corePrv = unity::dash::Preview::PreviewForProtocolObject(genPrv);
42− auto prv = Preview::newFromUnityPreview(core_prv);
52+ auto prv = Preview::newFromUnityPreview(corePrv);
43
53
44 QCOMPARE(prv != nullptr, true);
54 QCOMPARE(prv != nullptr, true);
45 QCOMPARE(prv->title(), QString("Metallica"));
55 QCOMPARE(prv->title(), QString("Metallica"));
46 QCOMPARE(prv->subtitle(), QString("Ride The Lightning"));
56 QCOMPARE(prv->subtitle(), QString("Ride The Lightning"));
47 QCOMPARE(prv->description(), QString("Lorem ipsum dolor sit amet"));
57 QCOMPARE(prv->description(), QString("Lorem ipsum dolor sit amet"));
58+
59+ auto actions = prv->actions().value<QList<QObject *>>();
60+ QCOMPARE(actions.size(), 1);
61+ auto act = dynamic_cast<PreviewAction *>(actions[0]);
62+ QVERIFY(act != nullptr);
63+ QCOMPARE(act->id(), QString("1"));
64+ QCOMPARE(act->displayName(), QString("Action1"));
65+ QCOMPARE(act->iconHint(), QString("/foo.png"));
66+
67+ g_object_unref(icon);
68+ g_object_unref(iconFile);
48}
69}
49
70
50void PreviewBindingsTest::testApplicationPreview()
71void PreviewBindingsTest::testApplicationPreview()
51{
72{
52− auto raw_preview = (GObject *)unity_protocol_application_preview_new();
73+ auto rawPreview = (GObject *)unity_protocol_application_preview_new();
53− unity_protocol_preview_set_title(UNITY_PROTOCOL_PREVIEW(raw_preview), "Firefox");
74+ unity_protocol_preview_set_title(UNITY_PROTOCOL_PREVIEW(rawPreview), "Firefox");
54− unity_protocol_preview_set_subtitle(UNITY_PROTOCOL_PREVIEW(raw_preview), "Web Browser");
75+ unity_protocol_preview_set_subtitle(UNITY_PROTOCOL_PREVIEW(rawPreview), "Web Browser");
55− unity_protocol_preview_set_description(UNITY_PROTOCOL_PREVIEW(raw_preview), "Lorem ipsum dolor sit amet");
76+ unity_protocol_preview_set_description(UNITY_PROTOCOL_PREVIEW(rawPreview), "Lorem ipsum dolor sit amet");
56− unity_protocol_application_preview_set_license(UNITY_PROTOCOL_APPLICATION_PREVIEW(raw_preview), "GPL");
77+ unity_protocol_application_preview_set_license(UNITY_PROTOCOL_APPLICATION_PREVIEW(rawPreview), "GPL");
57− unity_protocol_application_preview_set_rating(UNITY_PROTOCOL_APPLICATION_PREVIEW(raw_preview), 0.5f);
78+ unity_protocol_application_preview_set_rating(UNITY_PROTOCOL_APPLICATION_PREVIEW(rawPreview), 0.5f);
58− unity_protocol_application_preview_set_num_ratings(UNITY_PROTOCOL_APPLICATION_PREVIEW(raw_preview), 4);
79+ unity_protocol_application_preview_set_num_ratings(UNITY_PROTOCOL_APPLICATION_PREVIEW(rawPreview), 4);
59− unity::glib::Object<GObject> gen_prv(raw_preview);
80+ unity::glib::Object<GObject> genPrv(rawPreview);
60−
81+
61− auto core_prv = unity::dash::Preview::PreviewForProtocolObject(gen_prv);
82+ auto corePrv = unity::dash::Preview::PreviewForProtocolObject(genPrv);
62− auto prv = Preview::newFromUnityPreview(core_prv);
83+ auto prv = Preview::newFromUnityPreview(corePrv);
63− auto app_prv = dynamic_cast<ApplicationPreview*>(prv);
84+ auto appPrv = dynamic_cast<ApplicationPreview*>(prv);
64−
85+
65− QCOMPARE(app_prv != nullptr, true);
86+ QCOMPARE(appPrv != nullptr, true);
66− QCOMPARE(app_prv->title(), QString("Firefox"));
87+ QCOMPARE(appPrv->title(), QString("Firefox"));
67− QCOMPARE(app_prv->subtitle(), QString("Web Browser"));
88+ QCOMPARE(appPrv->subtitle(), QString("Web Browser"));
68− QCOMPARE(app_prv->description(), QString("Lorem ipsum dolor sit amet"));
89+ QCOMPARE(appPrv->description(), QString("Lorem ipsum dolor sit amet"));
69− QCOMPARE(app_prv->license(), QString("GPL"));
90+ QCOMPARE(appPrv->license(), QString("GPL"));
70− QCOMPARE(app_prv->rating(), 0.5f);
91+ QCOMPARE(appPrv->rating(), 0.5f);
71− QCOMPARE(app_prv->numRatings(), unsigned (4));
92+ QCOMPARE(appPrv->numRatings(), unsigned (4));
72}
93}
73
94
74void PreviewBindingsTest::testMoviePreview()
95void PreviewBindingsTest::testMoviePreview()
75{
96{
76− auto raw_preview = (GObject *)unity_protocol_movie_preview_new();
97+ auto rawPreview = (GObject *)unity_protocol_movie_preview_new();
77− unity_protocol_preview_set_title(UNITY_PROTOCOL_PREVIEW(raw_preview), "Blade Runner");
98+ unity_protocol_preview_set_title(UNITY_PROTOCOL_PREVIEW(rawPreview), "Blade Runner");
78− unity_protocol_preview_set_subtitle(UNITY_PROTOCOL_PREVIEW(raw_preview), "Ridley Scott");
99+ unity_protocol_preview_set_subtitle(UNITY_PROTOCOL_PREVIEW(rawPreview), "Ridley Scott");
79− unity_protocol_preview_set_description(UNITY_PROTOCOL_PREVIEW(raw_preview), "Lorem ipsum dolor sit amet");
100+ unity_protocol_preview_set_description(UNITY_PROTOCOL_PREVIEW(rawPreview), "Lorem ipsum dolor sit amet");
80− unity_protocol_movie_preview_set_year(UNITY_PROTOCOL_MOVIE_PREVIEW(raw_preview), "1982");
101+ unity_protocol_movie_preview_set_year(UNITY_PROTOCOL_MOVIE_PREVIEW(rawPreview), "1982");
81− unity::glib::Object<GObject> gen_prv(raw_preview);
102+ unity::glib::Object<GObject> genPrv(rawPreview);
82−
103+
83− auto core_prv = unity::dash::Preview::PreviewForProtocolObject(gen_prv);
104+ auto corePrv = unity::dash::Preview::PreviewForProtocolObject(genPrv);
84− auto prv = Preview::newFromUnityPreview(core_prv);
105+ auto prv = Preview::newFromUnityPreview(corePrv);
85− auto movie_prv = dynamic_cast<MoviePreview*>(prv);
106+ auto moviePrv = dynamic_cast<MoviePreview*>(prv);
86−
107+
87− QCOMPARE(movie_prv != nullptr, true);
108+ QCOMPARE(moviePrv != nullptr, true);
88− QCOMPARE(movie_prv->title(), QString("Blade Runner"));
109+ QCOMPARE(moviePrv->title(), QString("Blade Runner"));
89− QCOMPARE(movie_prv->subtitle(), QString("Ridley Scott"));
110+ QCOMPARE(moviePrv->subtitle(), QString("Ridley Scott"));
90− QCOMPARE(movie_prv->description(), QString("Lorem ipsum dolor sit amet"));
111+ QCOMPARE(moviePrv->description(), QString("Lorem ipsum dolor sit amet"));
91− QCOMPARE(movie_prv->year(), QString("1982"));
112+ QCOMPARE(moviePrv->year(), QString("1982"));
92}
113}
93
114
94void PreviewBindingsTest::testMusicPreview()
115void PreviewBindingsTest::testMusicPreview()
95{
116{
96− auto raw_preview = (GObject *)unity_protocol_music_preview_new();
117+ auto rawPreview = (GObject *)unity_protocol_music_preview_new();
97− unity_protocol_preview_set_title(UNITY_PROTOCOL_PREVIEW(raw_preview), "Metallica");
118+ unity_protocol_preview_set_title(UNITY_PROTOCOL_PREVIEW(rawPreview), "Metallica");
98− unity_protocol_preview_set_subtitle(UNITY_PROTOCOL_PREVIEW(raw_preview), "Death Magnetic");
119+ unity_protocol_preview_set_subtitle(UNITY_PROTOCOL_PREVIEW(rawPreview), "Death Magnetic");
99− unity_protocol_preview_set_description(UNITY_PROTOCOL_PREVIEW(raw_preview), "Lorem ipsum dolor sit amet");
120+ unity_protocol_preview_set_description(UNITY_PROTOCOL_PREVIEW(rawPreview), "Lorem ipsum dolor sit amet");
100− unity::glib::Object<GObject> gen_prv(raw_preview);
121+ unity::glib::Object<GObject> genPrv(rawPreview);
101−
122+
102− auto core_prv = unity::dash::Preview::PreviewForProtocolObject(gen_prv);
123+ auto corePrv = unity::dash::Preview::PreviewForProtocolObject(genPrv);
103− auto prv = Preview::newFromUnityPreview(core_prv);
124+ auto prv = Preview::newFromUnityPreview(corePrv);
104− auto music_prv = dynamic_cast<MusicPreview*>(prv);
125+ auto musicPrv = dynamic_cast<MusicPreview*>(prv);
105−
126+
106− QCOMPARE(music_prv != nullptr, true);
127+ QCOMPARE(musicPrv != nullptr, true);
107− QCOMPARE(music_prv->title(), QString("Metallica"));
128+ QCOMPARE(musicPrv->title(), QString("Metallica"));
108− QCOMPARE(music_prv->subtitle(), QString("Death Magnetic"));
129+ QCOMPARE(musicPrv->subtitle(), QString("Death Magnetic"));
109− QCOMPARE(music_prv->description(), QString("Lorem ipsum dolor sit amet"));
130+ QCOMPARE(musicPrv->description(), QString("Lorem ipsum dolor sit amet"));
131+}
132+
133+void PreviewBindingsTest::testSocialPreview()
134+{
135+ GFile *iconFile = g_file_new_for_path("/foo.png");
136+ GIcon *icon = g_file_icon_new(iconFile);
137+
138+ auto rawPreview = (GObject *)unity_protocol_social_preview_new();
139+ unity_protocol_social_preview_set_sender(UNITY_PROTOCOL_SOCIAL_PREVIEW(rawPreview), "John");
140+ unity_protocol_social_preview_set_avatar(UNITY_PROTOCOL_SOCIAL_PREVIEW(rawPreview), icon);
141+ unity_protocol_social_preview_set_content(UNITY_PROTOCOL_SOCIAL_PREVIEW(rawPreview), "Lorem ipsum dolor sit amet");
142+ unity_protocol_social_preview_add_comment(UNITY_PROTOCOL_SOCIAL_PREVIEW(rawPreview), "1", "comment1", "Ubuntu", "2013-07-04 14:10");
143+ unity::glib::Object<GObject> genPrv(rawPreview);
144+
145+ auto corePrv = unity::dash::Preview::PreviewForProtocolObject(genPrv);
146+ auto prv = Preview::newFromUnityPreview(corePrv);
147+ auto socialPrv = dynamic_cast<SocialPreview*>(prv);
148+
149+ QCOMPARE(socialPrv != nullptr, true);
150+ QCOMPARE(socialPrv->sender(), QString("John"));
151+ QCOMPARE(socialPrv->content(), QString("Lorem ipsum dolor sit amet"));
152+ QCOMPARE(socialPrv->avatar(), QString("/foo.png"));
153+
154+ auto comments = socialPrv->comments().value<QList<QObject *>>();
155+ QCOMPARE(comments.size(), 1);
156+ auto cmt = dynamic_cast<SocialPreviewComment *>(comments[0]);
157+ QVERIFY(cmt != nullptr);
158+ QCOMPARE(cmt->id(), QString("1"));
159+ QCOMPARE(cmt->displayName(), QString("comment1"));
160+ QCOMPARE(cmt->content(), QString("Ubuntu"));
161+ QCOMPARE(cmt->time(), QString("2013-07-04 14:10"));
162+
163+ g_object_unref(icon);
164+ g_object_unref(iconFile);
110}
165}
111
166
112QTEST_MAIN(PreviewBindingsTest)
167QTEST_MAIN(PreviewBindingsTest)
tests/plugins/Unity/previewbindingstest.h+1
@@ -29,6 +29,7 @@ class PreviewBindingsTest : public QObject
29 void testApplicationPreview();
29 void testApplicationPreview();
30 void testMoviePreview();
30 void testMoviePreview();
31 void testMusicPreview();
31 void testMusicPreview();
32+ void testSocialPreview();
32};
33};
33
34
34#endif
35#endif
tests/qmltests/Components/tst_OpenEffect.qml+1−1
@@ -28,7 +28,7 @@ TestCase {
28 function test_openeffect_shadereffectsource() {
28 function test_openeffect_shadereffectsource() {
29 compare(openEffect1.source.hideSource, true, "OpenEffect ShaderEffectSource is incorrect")
29 compare(openEffect1.source.hideSource, true, "OpenEffect ShaderEffectSource is incorrect")
30 compare(openEffect1.source.sourceItem, rectangle2, "OpenEffect ShaderEffectSource is incorrect")
30 compare(openEffect1.source.sourceItem, rectangle2, "OpenEffect ShaderEffectSource is incorrect")
31− compare(openEffect1.source.live, true, "OpenEffect ShaderEffectSource is incorrect")
31+ compare(openEffect1.source.live, false, "OpenEffect ShaderEffectSource is incorrect")
32 compare(openEffect1.source.sourceRect.x, 0, "OpenEffect ShaderEffectSource is incorrect")
32 compare(openEffect1.source.sourceRect.x, 0, "OpenEffect ShaderEffectSource is incorrect")
33 compare(openEffect1.source.sourceRect.y, 0, "OpenEffect ShaderEffectSource is incorrect")
33 compare(openEffect1.source.sourceRect.y, 0, "OpenEffect ShaderEffectSource is incorrect")
34 compare(openEffect1.source.sourceRect.width, 50, "OpenEffect ShaderEffectSource is incorrect")
34 compare(openEffect1.source.sourceRect.width, 50, "OpenEffect ShaderEffectSource is incorrect")
tests/qmltests/Dash/qml/FakeScopeView.qml+2−2
@@ -107,10 +107,10 @@ FocusScope {
107 Image {
107 Image {
108 width: units.gu(5)
108 width: units.gu(5)
109 height: units.gu(5)
109 height: units.gu(5)
110− source: column_1
110+ source: icon
111 anchors.horizontalCenter: parent.horizontalCenter
111 anchors.horizontalCenter: parent.horizontalCenter
112 }
112 }
113− Text { text: column_4; anchors.horizontalCenter: parent.horizontalCenter }
113+ Text { text: title; anchors.horizontalCenter: parent.horizontalCenter }
114 }
114 }
115 }
115 }
116 }
116 }
tests/qmltests/Dash/tst_FilterGrids.qml+20−20
@@ -53,26 +53,26 @@ Rectangle {
53
53
54 ListModel {
54 ListModel {
55 id: fakeModel
55 id: fakeModel
56− ListElement { column_0: "Column0"; column_1: "../../graphics/clock.png"; column_4: "Item0"; column_5: ""; column_6: "dummy.desktop" }
56+ ListElement { icon: "../../graphics/clock.png"; title: "Item0"; comment: ""; uri: "dummy.desktop"; dndUri: "dummy.desktop" }
57− ListElement { column_0: "Column0"; column_1: "../../graphics/clock.png"; column_4: "Item1"; column_5: ""; column_6: "dummy.desktop" }
57+ ListElement { icon: "../../graphics/clock.png"; title: "Item1"; comment: ""; uri: "dummy.desktop"; dndUri: "dummy.desktop" }
58− ListElement { column_0: "Column0"; column_1: "../../graphics/clock.png"; column_4: "Item2"; column_5: ""; column_6: "dummy.desktop" }
58+ ListElement { icon: "../../graphics/clock.png"; title: "Item2"; comment: ""; uri: "dummy.desktop"; dndUri: "dummy.desktop" }
59− ListElement { column_0: "Column0"; column_1: "../../graphics/clock.png"; column_4: "Item3"; column_5: ""; column_6: "dummy.desktop" }
59+ ListElement { icon: "../../graphics/clock.png"; title: "Item3"; comment: ""; uri: "dummy.desktop"; dndUri: "dummy.desktop" }
60− ListElement { column_0: "Column0"; column_1: "../../graphics/clock.png"; column_4: "Item4"; column_5: ""; column_6: "dummy.desktop" }
60+ ListElement { icon: "../../graphics/clock.png"; title: "Item4"; comment: ""; uri: "dummy.desktop"; dndUri: "dummy.desktop" }
61− ListElement { column_0: "Column0"; column_1: "../../graphics/clock.png"; column_4: "Item5"; column_5: ""; column_6: "dummy.desktop" }
61+ ListElement { icon: "../../graphics/clock.png"; title: "Item5"; comment: ""; uri: "dummy.desktop"; dndUri: "dummy.desktop" }
62− ListElement { column_0: "Column0"; column_1: "../../graphics/clock.png"; column_4: "Item6"; column_5: ""; column_6: "dummy.desktop" }
62+ ListElement { icon: "../../graphics/clock.png"; title: "Item6"; comment: ""; uri: "dummy.desktop"; dndUri: "dummy.desktop" }
63− ListElement { column_0: "Column0"; column_1: "../../graphics/clock.png"; column_4: "Item7"; column_5: ""; column_6: "dummy.desktop" }
63+ ListElement { icon: "../../graphics/clock.png"; title: "Item7"; comment: ""; uri: "dummy.desktop"; dndUri: "dummy.desktop" }
64− ListElement { column_0: "Column0"; column_1: "../../graphics/clock.png"; column_4: "Item8"; column_5: ""; column_6: "dummy.desktop" }
64+ ListElement { icon: "../../graphics/clock.png"; title: "Item8"; comment: ""; uri: "dummy.desktop"; dndUri: "dummy.desktop" }
65− ListElement { column_0: "Column0"; column_1: "../../graphics/clock.png"; column_4: "Item9"; column_5: ""; column_6: "dummy.desktop" }
65+ ListElement { icon: "../../graphics/clock.png"; title: "Item9"; comment: ""; uri: "dummy.desktop"; dndUri: "dummy.desktop" }
66− ListElement { column_0: "Column0"; column_1: "../../graphics/clock.png"; column_4: "Item10"; column_5: ""; column_6: "dummy.desktop" }
66+ ListElement { icon: "../../graphics/clock.png"; title: "Item10"; comment: ""; uri: "dummy.desktop"; dndUri: "dummy.desktop" }
67− ListElement { column_0: "Column0"; column_1: "../../graphics/clock.png"; column_4: "Item11"; column_5: ""; column_6: "dummy.desktop" }
67+ ListElement { icon: "../../graphics/clock.png"; title: "Item11"; comment: ""; uri: "dummy.desktop"; dndUri: "dummy.desktop" }
68− ListElement { column_0: "Column0"; column_1: "../../graphics/clock.png"; column_4: "Item12"; column_5: ""; column_6: "dummy.desktop" }
68+ ListElement { icon: "../../graphics/clock.png"; title: "Item12"; comment: ""; uri: "dummy.desktop"; dndUri: "dummy.desktop" }
69− ListElement { column_0: "Column0"; column_1: "../../graphics/clock.png"; column_4: "Item13"; column_5: ""; column_6: "dummy.desktop" }
69+ ListElement { icon: "../../graphics/clock.png"; title: "Item13"; comment: ""; uri: "dummy.desktop"; dndUri: "dummy.desktop" }
70− ListElement { column_0: "Column0"; column_1: "../../graphics/clock.png"; column_4: "Item14"; column_5: ""; column_6: "dummy.desktop" }
70+ ListElement { icon: "../../graphics/clock.png"; title: "Item14"; comment: ""; uri: "dummy.desktop"; dndUri: "dummy.desktop" }
71− ListElement { column_0: "Column0"; column_1: "../../graphics/clock.png"; column_4: "Item15"; column_5: ""; column_6: "dummy.desktop" }
71+ ListElement { icon: "../../graphics/clock.png"; title: "Item15"; comment: ""; uri: "dummy.desktop"; dndUri: "dummy.desktop" }
72− ListElement { column_0: "Column0"; column_1: "../../graphics/clock.png"; column_4: "Item16"; column_5: ""; column_6: "dummy.desktop" }
72+ ListElement { icon: "../../graphics/clock.png"; title: "Item16"; comment: ""; uri: "dummy.desktop"; dndUri: "dummy.desktop" }
73− ListElement { column_0: "Column0"; column_1: "../../graphics/clock.png"; column_4: "Item17"; column_5: ""; column_6: "dummy.desktop" }
73+ ListElement { icon: "../../graphics/clock.png"; title: "Item17"; comment: ""; uri: "dummy.desktop"; dndUri: "dummy.desktop" }
74− ListElement { column_0: "Column0"; column_1: "../../graphics/clock.png"; column_4: "Item18"; column_5: ""; column_6: "dummy.desktop" }
74+ ListElement { icon: "../../graphics/clock.png"; title: "Item18"; comment: ""; uri: "dummy.desktop"; dndUri: "dummy.desktop" }
75− ListElement { column_0: "Column0"; column_1: "../../graphics/clock.png"; column_4: "Item19"; column_5: ""; column_6: "dummy.desktop" }
75+ ListElement { icon: "../../graphics/clock.png"; title: "Item19"; comment: ""; uri: "dummy.desktop"; dndUri: "dummy.desktop" }
76 }
76 }
77
77
78 Rectangle {
78 Rectangle {