on xenial help sign in
Updated the Preview view to use a single PreviewModel instead old PreviewStack, using a Loader instead ListView Fixes: #1541967
05b99f2Andrea Cimitan
debian/control+1−1
@@ -29,7 +29,7 @@ Build-Depends: cmake,
29 libqt5xmlpatterns5-dev,
29 libqt5xmlpatterns5-dev,
30 libsystemsettings-dev,
30 libsystemsettings-dev,
31 libudev-dev,
31 libudev-dev,
32− libunity-api-dev (>= 7.106),
32+ libunity-api-dev (>= 7.107),
33 libusermetricsoutput1-dev,
33 libusermetricsoutput1-dev,
34# Need those X11 libs touch emulation from mouse events in manual QML tests on a X11 desktop
34# Need those X11 libs touch emulation from mouse events in manual QML tests on a X11 desktop
35 libx11-dev[!armhf],
35 libx11-dev[!armhf],
qml/Dash/GenericScopeView.qml+13−41
@@ -73,49 +73,30 @@ FocusScope {
73 }
73 }
74
74
75 property var maybePreviewResult;
75 property var maybePreviewResult;
76− property int maybePreviewIndex;
77− property var maybePreviewResultsModel;
78− property int maybePreviewLimitedCategoryItemCount;
79 property string maybePreviewCategoryId;
76 property string maybePreviewCategoryId;
80
77
81 function clearMaybePreviewData() {
78 function clearMaybePreviewData() {
82 scopeView.maybePreviewResult = undefined;
79 scopeView.maybePreviewResult = undefined;
83− scopeView.maybePreviewIndex = -1;
84− scopeView.maybePreviewResultsModel = undefined;
85− scopeView.maybePreviewLimitedCategoryItemCount = -1;
86 scopeView.maybePreviewCategoryId = "";
80 scopeView.maybePreviewCategoryId = "";
87 }
81 }
88
82
89− function itemClicked(index, result, itemModel, resultsModel, limitedCategoryItemCount, categoryId) {
83+ function itemClicked(result, categoryId) {
90 scopeView.maybePreviewResult = result;
84 scopeView.maybePreviewResult = result;
91− scopeView.maybePreviewIndex = index;
92− scopeView.maybePreviewResultsModel = resultsModel;
93− scopeView.maybePreviewLimitedCategoryItemCount = limitedCategoryItemCount;
94 scopeView.maybePreviewCategoryId = categoryId;
85 scopeView.maybePreviewCategoryId = categoryId;
95
86
96 scope.activate(result, categoryId);
87 scope.activate(result, categoryId);
97 }
88 }
98
89
99− function itemPressedAndHeld(index, result, resultsModel, limitedCategoryItemCount, categoryId) {
90+ function itemPressedAndHeld(result, categoryId) {
100 clearMaybePreviewData();
91 clearMaybePreviewData();
101
92
102− openPreview(result, index, resultsModel, limitedCategoryItemCount, categoryId);
93+ openPreview(result, categoryId);
103 }
94 }
104
95
105− function openPreview(result, index, resultsModel, limitedCategoryItemCount, categoryId) {
96+ function openPreview(result, categoryId) {
106− var previewStack = scope.preview(result, categoryId);
97+ var previewModel = scope.preview(result, categoryId);
107− if (previewStack) {
98+ if (previewModel) {
108− if (limitedCategoryItemCount > 0) {
99+ subPageLoader.previewModel = previewModel;
109− previewLimitModel.model = resultsModel;
110− previewLimitModel.limit = limitedCategoryItemCount;
111− subPageLoader.model = previewLimitModel;
112− } else {
113− subPageLoader.model = resultsModel;
114− }
115− subPageLoader.initialIndex = -1;
116− subPageLoader.initialIndex = index;
117− subPageLoader.categoryId = categoryId;
118− subPageLoader.previewStack = previewStack;
119 subPageLoader.openSubPage("preview");
100 subPageLoader.openSubPage("preview");
120 }
101 }
121 }
102 }
@@ -166,9 +147,6 @@ FocusScope {
166 onPreviewRequested: { // (QVariant const& result)
147 onPreviewRequested: { // (QVariant const& result)
167 if (result === scopeView.maybePreviewResult) {
148 if (result === scopeView.maybePreviewResult) {
168 openPreview(result,
149 openPreview(result,
169− scopeView.maybePreviewIndex,
170− scopeView.maybePreviewResultsModel,
171− scopeView.maybePreviewLimitedCategoryItemCount,
172 scopeView.maybePreviewCategoryId);
150 scopeView.maybePreviewCategoryId);
173
151
174 clearMaybePreviewData();
152 clearMaybePreviewData();
@@ -400,11 +378,11 @@ FocusScope {
400 Connections {
378 Connections {
401 target: rendererLoader.item
379 target: rendererLoader.item
402 onClicked: { // (int index, var result, var item, var itemModel)
380 onClicked: { // (int index, var result, var item, var itemModel)
403− scopeView.itemClicked(index, result, itemModel, target.model, categoryItemCount(), baseItem.category);
381+ scopeView.itemClicked(result, baseItem.category);
404 }
382 }
405
383
406 onPressAndHold: { // (int index, var result, var itemModel)
384 onPressAndHold: { // (int index, var result, var itemModel)
407− scopeView.itemPressedAndHeld(index, result, target.model, categoryItemCount(), baseItem.category);
385+ scopeView.itemPressedAndHeld(result, baseItem.category);
408 }
386 }
409
387
410 function categoryItemCount() {
388 function categoryItemCount() {
@@ -779,13 +757,10 @@ FocusScope {
779 property var scope: scopeView.scope
757 property var scope: scopeView.scope
780 property var scopeStyle: scopeView.scopeStyle
758 property var scopeStyle: scopeView.scopeStyle
781 property int initialIndex: -1
759 property int initialIndex: -1
782− property var previewStack;
760+ property var previewModel;
783− property string categoryId
784− property var model: null
785
761
786 readonly property bool processing: item && item.processing || false
762 readonly property bool processing: item && item.processing || false
787 readonly property int count: item && item.count || 0
763 readonly property int count: item && item.count || 0
788− readonly property int currentIndex: item && item.currentIndex || 0
789 readonly property var currentItem: item && item.currentItem || null
764 readonly property var currentItem: item && item.currentItem || null
790
765
791 property string subPage: ""
766 property string subPage: ""
@@ -800,7 +775,7 @@ FocusScope {
800 }
775 }
801
776
802 source: switch(subPage) {
777 source: switch(subPage) {
803− case "preview": return "PreviewListView.qml";
778+ case "preview": return "PreviewView.qml";
804 case "settings": return "ScopeSettingsPage.qml";
779 case "settings": return "ScopeSettingsPage.qml";
805 default: return "";
780 default: return "";
806 }
781 }
@@ -810,11 +785,8 @@ FocusScope {
810 item.scopeStyle = Qt.binding(function() { return subPageLoader.scopeStyle; } )
785 item.scopeStyle = Qt.binding(function() { return subPageLoader.scopeStyle; } )
811 if (subPage == "preview") {
786 if (subPage == "preview") {
812 item.open = Qt.binding(function() { return subPageLoader.open; } )
787 item.open = Qt.binding(function() { return subPageLoader.open; } )
813− item.initialIndex = Qt.binding(function() { return subPageLoader.initialIndex; } )
788+ item.previewModel = subPageLoader.previewModel;
814− item.model = Qt.binding(function() { return subPageLoader.model; } )
789+ subPageLoader.previewModel = null;
815− item.categoryId = Qt.binding(function() { return subPageLoader.categoryId; } )
816− item.initialIndexPreviewStack = subPageLoader.previewStack;
817− subPageLoader.previewStack = null;
818 }
790 }
819 open = true;
791 open = true;
820 }
792 }
qml/Dash/PreviewListView.qmldeleted−140
@@ -1,140 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.4
18−import Ubuntu.Components 1.3
19−import Unity 0.2
20−import "../Components"
21−import "Previews" as Previews
22−
23−Item {
24− id: root
25−
26− property int initialIndex: -1
27− property var initialIndexPreviewStack: null
28− property var scope: null
29− property var scopeStyle: null
30− property string categoryId
31− property bool usedInitialIndex: false
32−
33− property alias showSignatureLine: header.showSignatureLine
34−
35− property alias open: previewListView.open
36− property alias model: previewListView.model
37− property alias currentIndex: previewListView.currentIndex
38− property alias currentItem: previewListView.currentItem
39− property alias count: previewListView.count
40−
41− readonly property bool processing: currentItem && (!currentItem.previewModel.loaded
42− || currentItem.previewModel.processingAction)
43−
44− signal backClicked()
45−
46− DashPageHeader {
47− id: header
48− objectName: "pageHeader"
49− width: parent.width
50− title: root.scope ? root.scope.name : ""
51− showBackButton: true
52− searchEntryEnabled: false
53− scopeStyle: root.scopeStyle
54−
55− onBackClicked: root.backClicked()
56− }
57−
58− ListView {
59− id: previewListView
60− objectName: "listView"
61− anchors {
62− top: header.bottom
63− bottom: parent.bottom
64− left: parent.left
65− right: parent.right
66− }
67− orientation: ListView.Horizontal
68− highlightRangeMode: ListView.StrictlyEnforceRange
69− snapMode: ListView.SnapOneItem
70− boundsBehavior: Flickable.DragAndOvershootBounds
71− highlightMoveDuration: 250
72− flickDeceleration: units.gu(625)
73− maximumFlickVelocity: width * 5
74− cacheBuffer: 0
75−
76− property bool open: false
77−
78− onOpenChanged: {
79− if (!open) {
80− // Cancel any pending preview requests or actions
81− if (previewListView.currentItem && previewListView.currentItem.previewData !== undefined) {
82− previewListView.currentItem.previewData.cancelAction();
83− }
84− root.scope.cancelActivation();
85− model = undefined;
86− }
87− }
88−
89− onModelChanged: {
90− if (count > 0 && initialIndex >= 0 && !usedInitialIndex) {
91− usedInitialIndex = true;
92− previewListView.positionViewAtIndex(initialIndex, ListView.SnapPosition);
93− }
94− }
95−
96− delegate: Previews.Preview {
97− id: preview
98− objectName: "preview" + index
99− height: previewListView.height
100− width: previewListView.width
101−
102− isCurrent: ListView.isCurrentItem
103−
104− readonly property var previewStack: {
105− if (root.open) {
106− if (index === root.initialIndex) {
107− return root.initialIndexPreviewStack;
108− } else {
109− return root.scope.preview(result, root.categoryId);
110− }
111− } else {
112− return null;
113− }
114− }
115−
116− previewModel: {
117− if (previewStack) {
118− return previewStack.getPreviewModel(0);
119− } else {
120− return null;
121− }
122− }
123−
124− scopeStyle: root.scopeStyle
125− }
126− }
127−
128− MouseArea {
129− id: processingMouseArea
130− objectName: "processingMouseArea"
131− anchors {
132− left: parent.left
133− right: parent.right
134− top: header.bottom
135− bottom: parent.bottom
136− }
137−
138− enabled: root.processing
139− }
140−}
qml/Dash/PreviewView.qmlnew file+76
@@ -0,0 +1,76 @@
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.4
18+import Ubuntu.Components 1.3
19+import Unity 0.2
20+import "../Components"
21+import "Previews" as Previews
22+
23+Item {
24+ id: root
25+
26+ property bool open: false
27+ property var scope: null
28+ property var scopeStyle: null
29+ property alias showSignatureLine: header.showSignatureLine
30+ property alias previewModel: preview.previewModel
31+ readonly property bool processing: previewModel && (!previewModel.loaded || previewModel.processingAction)
32+
33+ signal backClicked()
34+
35+ DashPageHeader {
36+ id: header
37+ objectName: "pageHeader"
38+ width: parent.width
39+ title: root.scope ? root.scope.name : ""
40+ showBackButton: true
41+ searchEntryEnabled: false
42+ scopeStyle: root.scopeStyle
43+
44+ onBackClicked: root.backClicked()
45+ }
46+
47+ onOpenChanged: {
48+ if (!open) {
49+ root.scope.cancelActivation();
50+ }
51+ }
52+
53+ Previews.Preview {
54+ id: preview
55+ objectName: "preview"
56+ anchors {
57+ top: header.bottom
58+ bottom: parent.bottom
59+ left: parent.left
60+ right: parent.right
61+ }
62+ scopeStyle: root.scopeStyle
63+ }
64+
65+ MouseArea {
66+ id: processingMouseArea
67+ objectName: "processingMouseArea"
68+ anchors {
69+ top: header.bottom
70+ bottom: parent.bottom
71+ left: parent.left
72+ right: parent.right
73+ }
74+ enabled: root.processing
75+ }
76+}
qml/Dash/Previews/Preview.qml−4
@@ -34,9 +34,6 @@ Item {
34 */
34 */
35 property var previewModel
35 property var previewModel
36
36
37− //! \brief Should be set to true if this preview is currently displayed.
38− property bool isCurrent: false
39−
40 //! \brief The ScopeStyle component.
37 //! \brief The ScopeStyle component.
41 property var scopeStyle: null
38 property var scopeStyle: null
42
39
@@ -88,7 +85,6 @@ Item {
88 widgetId: model.widgetId
85 widgetId: model.widgetId
89 widgetType: model.type
86 widgetType: model.type
90 widgetData: model.properties
87 widgetData: model.properties
91− isCurrentPreview: root.isCurrent
92 scopeStyle: root.scopeStyle
88 scopeStyle: root.scopeStyle
93 parentFlickable: column
89 parentFlickable: column
94
90
qml/Dash/Previews/PreviewExpandable.qml−1
@@ -84,7 +84,6 @@ PreviewWidget {
84 widgetId: model.widgetId
84 widgetId: model.widgetId
85 widgetType: model.type
85 widgetType: model.type
86 widgetData: model.properties
86 widgetData: model.properties
87− isCurrentPreview: root.isCurrentPreview
88 scopeStyle: root.scopeStyle
87 scopeStyle: root.scopeStyle
89 anchors {
88 anchors {
90 left: parent.left
89 left: parent.left
qml/Dash/Previews/PreviewRatingDisplay.qml−1
@@ -40,7 +40,6 @@ PreviewWidget {
40 id: root
40 id: root
41 implicitHeight: childrenRect.height
41 implicitHeight: childrenRect.height
42
42
43− onIsCurrentPreviewChanged: ratingsList.updateRanges();
44 onParentFlickableChanged: ratingsList.updateRanges();
43 onParentFlickableChanged: ratingsList.updateRanges();
45
44
46 Connections {
45 Connections {
qml/Dash/Previews/PreviewRatingEdit.qml−1
@@ -68,7 +68,6 @@ PreviewWidget {
68
68
69 widgetId: root.widgetId
69 widgetId: root.widgetId
70 widgetData: root.widgetData
70 widgetData: root.widgetData
71− isCurrentPreview: root.isCurrentPreview
72 scopeStyle: root.scopeStyle
71 scopeStyle: root.scopeStyle
73
72
74 ratingValue: widgetData["rating"]
73 ratingValue: widgetData["rating"]
qml/Dash/Previews/PreviewWidget.qml−3
@@ -19,9 +19,6 @@ import QtQuick 2.4
19/*! Interface for preview widgets. */
19/*! Interface for preview widgets. */
20
20
21Item {
21Item {
22− //! Specifies the preview widget being currently used or not
23− property bool isCurrentPreview: true
24−
25 //! The widget identifier
22 //! The widget identifier
26 property string widgetId
23 property string widgetId
27
24
qml/Dash/Previews/PreviewWidgetFactory.qml−4
@@ -37,9 +37,6 @@ Loader {
37 //! Should the widget show in expanded mode (For those that support it)
37 //! Should the widget show in expanded mode (For those that support it)
38 property bool expanded: widgetType !== "expandable" || widgetData["expanded"] === true
38 property bool expanded: widgetType !== "expandable" || widgetData["expanded"] === true
39
39
40− //! Set to true if the parent preview is displayed.
41− property bool isCurrentPreview: false
42−
43 //! Set margins width.
40 //! Set margins width.
44 property real widgetMargins: status === Loader.Ready ? item.widgetMargins : units.gu(1)
41 property real widgetMargins: status === Loader.Ready ? item.widgetMargins : units.gu(1)
45
42
@@ -82,7 +79,6 @@ Loader {
82 onLoaded: {
79 onLoaded: {
83 item.widgetId = Qt.binding(function() { return root.widgetId } )
80 item.widgetId = Qt.binding(function() { return root.widgetId } )
84 item.widgetData = Qt.binding(function() { return root.widgetData } )
81 item.widgetData = Qt.binding(function() { return root.widgetData } )
85− item.isCurrentPreview = Qt.binding(function() { return root.isCurrentPreview } )
86 item.expanded = Qt.binding(function() { return root.expanded } )
82 item.expanded = Qt.binding(function() { return root.expanded } )
87 item.scopeStyle = Qt.binding(function() { return root.scopeStyle } )
83 item.scopeStyle = Qt.binding(function() { return root.scopeStyle } )
88 item.parentFlickable = Qt.binding(function() { return root.parentFlickable } )
84 item.parentFlickable = Qt.binding(function() { return root.parentFlickable } )
tests/mocks/Unity/CMakeLists.txt−2
@@ -28,13 +28,11 @@ set(UnityQML_SOURCES
28 fake_navigation.cpp
28 fake_navigation.cpp
29 fake_resultsmodel.cpp
29 fake_resultsmodel.cpp
30 fake_previewmodel.cpp
30 fake_previewmodel.cpp
31− fake_previewstack.cpp
32 fake_previewwidgetmodel.cpp
31 fake_previewwidgetmodel.cpp
33 fake_unity_plugin.cpp
32 fake_unity_plugin.cpp
34 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/CategoriesInterface.h
33 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/CategoriesInterface.h
35 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/NavigationInterface.h
34 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/NavigationInterface.h
36 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewModelInterface.h
35 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewModelInterface.h
37− ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewStackInterface.h
38 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewWidgetModelInterface.h
36 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewWidgetModelInterface.h
39 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/ResultsModelInterface.h
37 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/ResultsModelInterface.h
40 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/ScopeInterface.h
38 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/ScopeInterface.h
tests/mocks/Unity/Unity.qmltypes+33−50
@@ -1,4 +1,4 @@
1−import QtQuick.tooling 1.1
1+import QtQuick.tooling 1.2
2
2
3// This file describes the plugin-supplied types contained in the library.
3// This file describes the plugin-supplied types contained in the library.
4// It is used for QML tooling purposes only.
4// It is used for QML tooling purposes only.
@@ -7,17 +7,10 @@ import QtQuick.tooling 1.1
7// 'qmlplugindump -notrelocatable Unity 0.2 tests/mocks'
7// 'qmlplugindump -notrelocatable Unity 0.2 tests/mocks'
8
8
9Module {
9Module {
10+ dependencies: ["QtQuick 2.4", "Unity.Indicators 0.1"]
10 Component {
11 Component {
11 name: "Categories"
12 name: "Categories"
12 prototype: "unity::shell::scopes::CategoriesInterface"
13 prototype: "unity::shell::scopes::CategoriesInterface"
13− Method {
14− name: "addSpecialCategory"
15− Parameter { name: "categoryId"; type: "string" }
16− Parameter { name: "name"; type: "string" }
17− Parameter { name: "icon"; type: "string" }
18− Parameter { name: "rawTemplate"; type: "string" }
19− Parameter { name: "countObject"; type: "QObject"; isPointer: true }
20− }
21 Method {
14 Method {
22 name: "overrideCategoryJson"
15 name: "overrideCategoryJson"
23 type: "bool"
16 type: "bool"
@@ -60,18 +53,6 @@ Module {
60 Parameter { type: "bool" }
53 Parameter { type: "bool" }
61 }
54 }
62 }
55 }
63− Component {
64− name: "PreviewStack"
65− prototype: "unity::shell::scopes::PreviewStackInterface"
66− exports: ["Unity/PreviewStack 0.2"]
67− isCreatable: false
68− exportMetaObjectRevisions: [0]
69− Method {
70− name: "getPreviewModel"
71− type: "unity::shell::scopes::PreviewModelInterface*"
72− Parameter { name: "index"; type: "int" }
73− }
74− }
75 Component {
56 Component {
76 name: "PreviewWidgetModel"
57 name: "PreviewWidgetModel"
77 prototype: "unity::shell::scopes::PreviewWidgetModelInterface"
58 prototype: "unity::shell::scopes::PreviewWidgetModelInterface"
@@ -95,11 +76,11 @@ Module {
95 prototype: "unity::shell::scopes::ScopeInterface"
76 prototype: "unity::shell::scopes::ScopeInterface"
96 exports: ["Unity/MockScope 0.2"]
77 exports: ["Unity/MockScope 0.2"]
97 exportMetaObjectRevisions: [0]
78 exportMetaObjectRevisions: [0]
79+ Signal { name: "refreshed" }
98 Signal {
80 Signal {
99− name: "performQuery"
81+ name: "queryPerformed"
100 Parameter { name: "query"; type: "string" }
82 Parameter { name: "query"; type: "string" }
101 }
83 }
102− Signal { name: "refreshed" }
103 Method {
84 Method {
104 name: "setId"
85 name: "setId"
105 Parameter { name: "id"; type: "string" }
86 Parameter { name: "id"; type: "string" }
@@ -115,11 +96,13 @@ Module {
115 Method {
96 Method {
116 name: "activate"
97 name: "activate"
117 Parameter { name: "result"; type: "QVariant" }
98 Parameter { name: "result"; type: "QVariant" }
99+ Parameter { name: "categoryId"; type: "string" }
118 }
100 }
119 Method {
101 Method {
120 name: "preview"
102 name: "preview"
121− type: "PreviewStack*"
103+ type: "PreviewModel*"
122 Parameter { name: "result"; type: "QVariant" }
104 Parameter { name: "result"; type: "QVariant" }
105+ Parameter { name: "categoryId"; type: "string" }
123 }
106 }
124 Method { name: "cancelActivation" }
107 Method { name: "cancelActivation" }
125 Method {
108 Method {
@@ -142,6 +125,12 @@ Module {
142 Parameter { name: "isAltNavigation"; type: "bool" }
125 Parameter { name: "isAltNavigation"; type: "bool" }
143 }
126 }
144 Method { name: "refresh" }
127 Method { name: "refresh" }
128+ Method {
129+ name: "activateAction"
130+ Parameter { name: "result"; type: "QVariant" }
131+ Parameter { name: "categoryId"; type: "string" }
132+ Parameter { name: "actionId"; type: "string" }
133+ }
145 }
134 }
146 Component {
135 Component {
147 name: "Scopes"
136 name: "Scopes"
@@ -181,6 +170,10 @@ Module {
181 Parameter { name: "scopeId"; type: "string" }
170 Parameter { name: "scopeId"; type: "string" }
182 Parameter { name: "index"; type: "int" }
171 Parameter { name: "index"; type: "int" }
183 }
172 }
173+ Method {
174+ name: "closeScope"
175+ Parameter { name: "scope"; type: "unity::shell::scopes::ScopeInterface"; isPointer: true }
176+ }
184 Method {
177 Method {
185 name: "getScopeFromAll"
178 name: "getScopeFromAll"
186 type: "Scope*"
179 type: "Scope*"
@@ -214,14 +207,6 @@ Module {
214 Parameter { name: "categoryId"; type: "string" }
207 Parameter { name: "categoryId"; type: "string" }
215 Parameter { name: "json"; type: "string" }
208 Parameter { name: "json"; type: "string" }
216 }
209 }
217− Method {
218− name: "addSpecialCategory"
219− Parameter { name: "categoryId"; type: "string" }
220− Parameter { name: "name"; type: "string" }
221− Parameter { name: "icon"; type: "string" }
222− Parameter { name: "rawTemplate"; type: "string" }
223− Parameter { name: "countObject"; type: "QObject"; isPointer: true }
224− }
225 }
210 }
226 Component {
211 Component {
227 name: "unity::shell::scopes::NavigationInterface"
212 name: "unity::shell::scopes::NavigationInterface"
@@ -270,22 +255,6 @@ Module {
270 Parameter { type: "QVariantMap" }
255 Parameter { type: "QVariantMap" }
271 }
256 }
272 }
257 }
273− Component {
274− name: "unity::shell::scopes::PreviewStackInterface"
275− prototype: "QAbstractListModel"
276− Enum {
277− name: "Roles"
278− values: {
279− "RolePreviewModel": 0
280− }
281− }
282− Property { name: "widgetColumnCount"; type: "int" }
283− Method {
284− name: "getPreviewModel"
285− type: "unity::shell::scopes::PreviewModelInterface*"
286− Parameter { name: "index"; type: "int" }
287− }
288− }
289 Component {
258 Component {
290 name: "unity::shell::scopes::PreviewWidgetModelInterface"
259 name: "unity::shell::scopes::PreviewWidgetModelInterface"
291 prototype: "QAbstractListModel"
260 prototype: "QAbstractListModel"
@@ -316,7 +285,8 @@ Module {
316 "RoleSummary": 9,
285 "RoleSummary": 9,
317 "RoleAttributes": 10,
286 "RoleAttributes": 10,
318 "RoleBackground": 11,
287 "RoleBackground": 11,
319− "RoleOverlayColor": 12
288+ "RoleOverlayColor": 12,
289+ "RoleQuickPreviewData": 13
320 }
290 }
321 }
291 }
322 Property { name: "categoryId"; type: "string" }
292 Property { name: "categoryId"; type: "string" }
@@ -343,6 +313,7 @@ Module {
343 Property { name: "description"; type: "string"; isReadonly: true }
313 Property { name: "description"; type: "string"; isReadonly: true }
344 Property { name: "searchHint"; type: "string"; isReadonly: true }
314 Property { name: "searchHint"; type: "string"; isReadonly: true }
345 Property { name: "searchInProgress"; type: "bool"; isReadonly: true }
315 Property { name: "searchInProgress"; type: "bool"; isReadonly: true }
316+ Property { name: "activationInProgress"; type: "bool"; isReadonly: true }
346 Property { name: "favorite"; type: "bool" }
317 Property { name: "favorite"; type: "bool" }
347 Property { name: "shortcut"; type: "string"; isReadonly: true }
318 Property { name: "shortcut"; type: "string"; isReadonly: true }
348 Property {
319 Property {
@@ -393,11 +364,13 @@ Module {
393 Method {
364 Method {
394 name: "activate"
365 name: "activate"
395 Parameter { name: "result"; type: "QVariant" }
366 Parameter { name: "result"; type: "QVariant" }
367+ Parameter { name: "categoryId"; type: "string" }
396 }
368 }
397 Method {
369 Method {
398 name: "preview"
370 name: "preview"
399− type: "unity::shell::scopes::PreviewStackInterface*"
371+ type: "unity::shell::scopes::PreviewModelInterface*"
400 Parameter { name: "result"; type: "QVariant" }
372 Parameter { name: "result"; type: "QVariant" }
373+ Parameter { name: "categoryId"; type: "string" }
401 }
374 }
402 Method { name: "cancelActivation" }
375 Method { name: "cancelActivation" }
403 Method {
376 Method {
@@ -424,6 +397,12 @@ Module {
424 Parameter { name: "cannedQuery"; type: "string" }
397 Parameter { name: "cannedQuery"; type: "string" }
425 }
398 }
426 Method { name: "refresh" }
399 Method { name: "refresh" }
400+ Method {
401+ name: "activateAction"
402+ Parameter { name: "result"; type: "QVariant" }
403+ Parameter { name: "categoryId"; type: "string" }
404+ Parameter { name: "actionId"; type: "string" }
405+ }
427 }
406 }
428 Component {
407 Component {
429 name: "unity::shell::scopes::ScopesInterface"
408 name: "unity::shell::scopes::ScopesInterface"
@@ -464,6 +443,10 @@ Module {
464 Parameter { name: "scopeId"; type: "string" }
443 Parameter { name: "scopeId"; type: "string" }
465 Parameter { name: "index"; type: "int" }
444 Parameter { name: "index"; type: "int" }
466 }
445 }
446+ Method {
447+ name: "closeScope"
448+ Parameter { name: "scope"; type: "unity::shell::scopes::ScopeInterface"; isPointer: true }
449+ }
467 }
450 }
468 Component {
451 Component {
469 name: "unity::shell::scopes::SettingsModelInterface"
452 name: "unity::shell::scopes::SettingsModelInterface"
tests/mocks/Unity/fake_previewstack.cppdeleted−68
@@ -1,68 +0,0 @@
1−/*
2− * Copyright (C) 2014 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−// self
18−#include "fake_previewstack.h"
19−
20−// local
21−#include "fake_previewmodel.h"
22−#include "fake_scope.h"
23−
24−PreviewStack::PreviewStack(Scope *scope)
25− : unity::shell::scopes::PreviewStackInterface(nullptr)
26−{
27− m_previews << new PreviewModel(this, scope);
28−}
29−
30−PreviewStack::~PreviewStack()
31−{
32−}
33−
34−void PreviewStack::setWidgetColumnCount(int columnCount)
35−{
36− if (columnCount != 1) {
37− qFatal("PreviewStack::setWidgetColumnCount != 1 not implemented");
38− }
39−}
40−
41−int PreviewStack::widgetColumnCount() const
42−{
43− return 1;
44−}
45−
46−int PreviewStack::rowCount(const QModelIndex&) const
47−{
48− return m_previews.size();
49−}
50−
51−unity::shell::scopes::PreviewModelInterface* PreviewStack::getPreviewModel(int index) const
52−{
53− if (index >= m_previews.size()) {
54− return nullptr;
55− }
56−
57− return m_previews.at(index);
58−}
59−
60−QVariant PreviewStack::data(const QModelIndex& index, int role) const
61−{
62− switch (role) {
63− case RolePreviewModel:
64− return QVariant::fromValue(m_previews.at(index.row()));
65− default:
66− return QVariant();
67− }
68−}
tests/mocks/Unity/fake_previewstack.hdeleted−52
@@ -1,52 +0,0 @@
1−/*
2− * Copyright (C) 2014 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−
18−#ifndef FAKE_PREVIEWSTACK_H
19−#define FAKE_PREVIEWSTACK_H
20−
21−#include <unity/shell/scopes/PreviewStackInterface.h>
22−
23−#include <QSharedPointer>
24−#include <QVariantMap>
25−
26−class PreviewModel;
27−
28−class Scope;
29−
30−class PreviewStack : public unity::shell::scopes::PreviewStackInterface
31−{
32− Q_OBJECT
33−
34−public:
35− explicit PreviewStack(Scope* scope = 0);
36− virtual ~PreviewStack();
37−
38− QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
39− int rowCount(const QModelIndex& parent = QModelIndex()) const override;
40−
41− Q_INVOKABLE unity::shell::scopes::PreviewModelInterface* getPreviewModel(int index) const override;
42−
43− void setWidgetColumnCount(int columnCount) override;
44− int widgetColumnCount() const override;
45−
46−private:
47− QList<PreviewModel*> m_previews;
48−};
49−
50−Q_DECLARE_METATYPE(PreviewStack*)
51−
52−#endif // FAKE_PREVIEWSTACK_H
tests/mocks/Unity/fake_scope.cpp+2−2
@@ -199,14 +199,14 @@ void Scope::activate(QVariant const& result, QString const& categoryId)
199 }
199 }
200}
200}
201
201
202−PreviewStack* Scope::preview(QVariant const& result, QString const& /*categoryId*/)
202+PreviewModel* Scope::preview(QVariant const& result, QString const& /*categoryId*/)
203{
203{
204 Q_UNUSED(result);
204 Q_UNUSED(result);
205
205
206 if (m_returnNullPreview) {
206 if (m_returnNullPreview) {
207 return nullptr;
207 return nullptr;
208 } else {
208 } else {
209− return new PreviewStack(this);
209+ return new PreviewModel(this, this);
210 }
210 }
211}
211}
212
212
tests/mocks/Unity/fake_scope.h+2−2
@@ -20,7 +20,7 @@
20#include <unity/shell/scopes/ScopeInterface.h>
20#include <unity/shell/scopes/ScopeInterface.h>
21
21
22#include "fake_categories.h"
22#include "fake_categories.h"
23−#include "fake_previewstack.h"
23+#include "fake_previewmodel.h"
24
24
25#include <QTimer>
25#include <QTimer>
26
26
@@ -62,7 +62,7 @@ public:
62 Q_INVOKABLE void setSearchInProgress(const bool inProg); // This is not invokable in the Interface, here for testing benefits
62 Q_INVOKABLE void setSearchInProgress(const bool inProg); // This is not invokable in the Interface, here for testing benefits
63
63
64 Q_INVOKABLE void activate(QVariant const& result, QString const& categoryId) override;
64 Q_INVOKABLE void activate(QVariant const& result, QString const& categoryId) override;
65− Q_INVOKABLE PreviewStack* preview(QVariant const& result, QString const& categoryId) override;
65+ Q_INVOKABLE PreviewModel* preview(QVariant const& result, QString const& categoryId) override;
66 Q_INVOKABLE void cancelActivation() override;
66 Q_INVOKABLE void cancelActivation() override;
67 Q_INVOKABLE void closeScope(unity::shell::scopes::ScopeInterface* scope) override;
67 Q_INVOKABLE void closeScope(unity::shell::scopes::ScopeInterface* scope) override;
68
68
tests/mocks/Unity/fake_unity_plugin.cpp+1−2
@@ -47,10 +47,9 @@ void FakeUnityPlugin::registerTypes(const char *uri)
47 qmlRegisterUncreatableType<unity::shell::scopes::SettingsModelInterface>(uri, 0, 2, "SettingsModel", "Can't create SettingsModel object in QML.");
47 qmlRegisterUncreatableType<unity::shell::scopes::SettingsModelInterface>(uri, 0, 2, "SettingsModel", "Can't create SettingsModel object in QML.");
48 qmlRegisterUncreatableType<unity::shell::scopes::NavigationInterface>(uri, 0, 2, "Navigation", "Can't create Navigation object in QML.");
48 qmlRegisterUncreatableType<unity::shell::scopes::NavigationInterface>(uri, 0, 2, "Navigation", "Can't create Navigation object in QML.");
49 qmlRegisterUncreatableType<unity::shell::scopes::CategoriesInterface>(uri, 0, 2, "Categories", "Can't create Categories object in QML.");
49 qmlRegisterUncreatableType<unity::shell::scopes::CategoriesInterface>(uri, 0, 2, "Categories", "Can't create Categories object in QML.");
50− qmlRegisterUncreatableType<unity::shell::scopes::PreviewModelInterface>(uri, 0, 2, "PreviewModel", "Can't create new PreviewModel in QML. Get them from PreviewStack instance.");
50+ qmlRegisterUncreatableType<unity::shell::scopes::PreviewModelInterface>(uri, 0, 2, "PreviewModel", "Can't create new PreviewModel in QML. Get them from Scope instance.");
51 qmlRegisterUncreatableType<ResultsModel>(uri, 0, 2, "ResultsModel", "Can't create ResultsModel object in QML.");
51 qmlRegisterUncreatableType<ResultsModel>(uri, 0, 2, "ResultsModel", "Can't create ResultsModel object in QML.");
52 qmlRegisterType<ResultsModel>(uri, 0, 2, "FakeResultsModel");
52 qmlRegisterType<ResultsModel>(uri, 0, 2, "FakeResultsModel");
53 qmlRegisterType<PreviewModel>(uri, 0, 2, "FakePreviewModel");
53 qmlRegisterType<PreviewModel>(uri, 0, 2, "FakePreviewModel");
54 qmlRegisterUncreatableType<PreviewWidgetModel>(uri, 0, 2, "PreviewWidgetModel", "Can't create new PreviewWidgetModel in QML. Get them from PreviewModel instance.");
54 qmlRegisterUncreatableType<PreviewWidgetModel>(uri, 0, 2, "PreviewWidgetModel", "Can't create new PreviewWidgetModel in QML. Get them from PreviewModel instance.");
55− qmlRegisterUncreatableType<PreviewStack>(uri, 0, 2, "PreviewStack", "Can't create new PreviewStack in QML. Get them from Scope instance.");
56}
55}
tests/qmltests/CMakeLists.txt+1−1
@@ -29,7 +29,7 @@ add_unity8_qmlbenchmark(Dash CardBenchmark 1000)
29add_unity8_qmltest(Dash CardTool)
29add_unity8_qmltest(Dash CardTool)
30add_unity8_qmltest(Dash GenericScopeView)
30add_unity8_qmltest(Dash GenericScopeView)
31add_unity8_qmltest(Dash DashPageHeader)
31add_unity8_qmltest(Dash DashPageHeader)
32−add_unity8_qmltest(Dash PreviewListView)
32+add_unity8_qmltest(Dash PreviewView)
33add_unity8_qmltest(Dash/Previews Preview)
33add_unity8_qmltest(Dash/Previews Preview)
34add_unity8_qmltest(Dash/Previews PreviewActions)
34add_unity8_qmltest(Dash/Previews PreviewActions)
35add_unity8_qmltest(Dash/Previews PreviewAudioPlayback)
35add_unity8_qmltest(Dash/Previews PreviewAudioPlayback)
tests/qmltests/Dash/tst_GenericScopeView.qml−28
@@ -236,12 +236,6 @@ Item {
236 verify(seeAll, "Can't find the seeAll element");
236 verify(seeAll, "Can't find the seeAll element");
237
237
238 compare(seeAll.height, 0, "SeeAll should be 0-height.");
238 compare(seeAll.height, 0, "SeeAll should be 0-height.");
239−
240− openPreview(4, 0);
241−
242− compare(testCase.subPageLoader.count, 16, "There should only be 16 items in preview.");
243−
244− closePreview();
245 }
239 }
246
240
247 function test_narrow_delegate_ranges_expand() {
241 function test_narrow_delegate_ranges_expand() {
@@ -404,28 +398,6 @@ Item {
404 closePreview();
398 closePreview();
405 }
399 }
406
400
407− function test_previewCycle() {
408− var categoryListView = findChild(genericScopeView, "categoryListView");
409− categoryListView.positionAtBeginning();
410−
411− tryCompare(testCase.subPageLoader, "open", false);
412−
413− openPreview();
414− var previewListViewList = findChild(subPageLoader.item, "listView");
415−
416− // flick to the next previews
417− tryCompare(testCase.subPageLoader, "count", 25);
418− for (var i = 1; i < testCase.subPageLoader.count; ++i) {
419− mouseFlick(testCase.subPageLoader.item, testCase.subPageLoader.width - units.gu(1),
420− testCase.subPageLoader.height / 2,
421− units.gu(2),
422− testCase.subPageLoader.height / 2);
423− tryCompare(previewListViewList, "moving", false);
424− tryCompare(testCase.subPageLoader.currentItem, "objectName", "preview" + i);
425− }
426− closePreview();
427− }
428−
429 function test_settingsOpenClose() {
401 function test_settingsOpenClose() {
430 waitForRendering(genericScopeView);
402 waitForRendering(genericScopeView);
431 verify(header, "Could not find the header.");
403 verify(header, "Could not find the header.");
tests/qmltests/Dash/tst_PreviewListView.qml → tests/qmltests/Dash/tst_PreviewView.qmlrenamed+23−16
@@ -36,8 +36,8 @@ Rectangle {
36 id: mockResultsModel
36 id: mockResultsModel
37 }
37 }
38
38
39− PreviewListView {
39+ PreviewView {
40− id: listView
40+ id: view
41 anchors.fill: parent
41 anchors.fill: parent
42 scope: mockScope
42 scope: mockScope
43 scopeStyle: ScopeStyle {
43 scopeStyle: ScopeStyle {
@@ -45,12 +45,22 @@ Rectangle {
45 }
45 }
46 }
46 }
47
47
48+ Item {
49+ Repeater {
50+ id: repeater
51+ model: mockResultsModel
52+ Item {
53+ property var previewModel: mockScope.preview(model.result, model.categoryId);
54+ }
55+ }
56+ }
57+
48 UT.UnityTestCase {
58 UT.UnityTestCase {
49 id: testCase
59 id: testCase
50− name: "PreviewListView"
60+ name: "PreviewView"
51 when: windowShown
61 when: windowShown
52
62
53− property MouseArea mouseArea: findChild(listView, "processingMouseArea")
63+ property MouseArea mouseArea: findChild(view, "processingMouseArea")
54
64
55 SignalSpy {
65 SignalSpy {
56 id: clickedSpy
66 id: clickedSpy
@@ -59,43 +69,40 @@ Rectangle {
59 }
69 }
60
70
61 function init() {
71 function init() {
62− listView.model = mockResultsModel;
63− listView.currentIndex = 1;
64− listView.open = true;
72+ view.open = true;
73+ view.previewModel = repeater.itemAt(0).previewModel
65 verify(testCase.mouseArea, "Can't find the processingMouseArea object.");
74 verify(testCase.mouseArea, "Can't find the processingMouseArea object.");
66 }
75 }
67
76
68 function cleanup() {
77 function cleanup() {
69− listView.open = false;
78+ view.open = false;
70− listView.model = null;
71 clickedSpy.clear();
79 clickedSpy.clear();
72 }
80 }
73
81
74 function test_notProcessing() {
82 function test_notProcessing() {
75 expectFail("", "processingMouseArea should not receive the click.");
83 expectFail("", "processingMouseArea should not receive the click.");
76− mouseClick(listView);
84+ mouseClick(view);
77 clickedSpy.wait();
85 clickedSpy.wait();
78 }
86 }
79
87
80 function test_processing() {
88 function test_processing() {
81− verify(listView.currentItem, "currentItem is not ready yet");
82− listView.currentItem.previewModel.setLoaded(false);
89+ view.previewModel.setLoaded(false);
83
90
84− tryCompare(listView, "processing", true);
91+ tryCompare(view, "processing", true);
85
92
86− mouseClick(listView);
93+ mouseClick(view);
87 clickedSpy.wait();
94 clickedSpy.wait();
88 }
95 }
89
96
90 function test_title() {
97 function test_title() {
91− var header = findChild(listView, "innerPageHeader");
98+ var header = findChild(view, "innerPageHeader");
92 verify(header, "Could not find the preview header");
99 verify(header, "Could not find the preview header");
93
100
94 compare(header.config.title, "Mock Scope");
101 compare(header.config.title, "Mock Scope");
95 }
102 }
96
103
97 function test_header_style() {
104 function test_header_style() {
98− var header = findChild(listView, "pageHeader");
105+ var header = findChild(view, "pageHeader");
99 verify(header, "Could not find the header");
106 verify(header, "Could not find the header");
100
107
101 var innerHeader = findChild(header, "innerPageHeader");
108 var innerHeader = findChild(header, "innerPageHeader");