on xenial help sign in
Add support for category header links.
63f2269Michał Sawicz
debian/control+1−1
@@ -108,7 +108,7 @@ Depends: qtdeclarative5-ubuntu-thumbnailer0.1 | ubuntu-thumbnailer-impl,
108 unity-application-impl-2,
108 unity-application-impl-2,
109 unity-notifications-impl-3,
109 unity-notifications-impl-3,
110 unity-plugin-scopes | unity-scopes-impl,
110 unity-plugin-scopes | unity-scopes-impl,
111− unity-scopes-impl-0,
111+ unity-scopes-impl-2,
112 unity8-fake-env | unity-application-impl,
112 unity8-fake-env | unity-application-impl,
113 ${misc:Depends},
113 ${misc:Depends},
114Breaks: unity8 (<< 7.86),
114Breaks: unity8 (<< 7.86),
qml/Components/ListItems/Header.qml+16−26
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013,2014 Canonical, Ltd.
3 *
3 *
4 * 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
5 * 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
@@ -18,51 +18,41 @@ import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19
19
20Item {
20Item {
21− /*!
22− \preliminary
23− The text that is shown as the header text.
24− \qmlproperty string text
25− */
26 property alias text: label.text
21 property alias text: label.text
27− property alias textColor: label.color
22+ property alias color: label.color
28− property alias image: image.source
23+ property alias iconName: icon.name
29
24
30 signal clicked(variant mouse)
25 signal clicked(variant mouse)
31
26
32 height: units.gu(5)
27 height: units.gu(5)
33
28
34− Item {
29+ Row {
30+ spacing: units.gu(.5)
35 anchors {
31 anchors {
36 left: parent.left
32 left: parent.left
37 right: parent.right
33 right: parent.right
34+ verticalCenter: parent.verticalCenter
38− rightMargin: units.gu(0.5)
35+ margins: units.gu(1)
39− top: parent.top
40− bottom: parent.bottom
41 }
36 }
42
37
43 Label {
38 Label {
44 id: label
39 id: label
45− anchors {
46− left: parent.left
47− leftMargin: units.gu(2)
48− verticalCenter: parent.verticalCenter
49− }
50
40
51− color: "grey" // TODO karni: Update Ubuntu.Compoonents.Themes.Palette.
52 font.family: "Ubuntu"
41 font.family: "Ubuntu"
53 fontSize: "medium"
42 fontSize: "medium"
54 elide: Text.ElideRight
43 elide: Text.ElideRight
44+ maximumLineCount: 1
55 textFormat: Text.PlainText
45 textFormat: Text.PlainText
56− width: parent.width - image.width - image.leftMargin - anchors.leftMargin
46+ width: Math.min(parent.width - units.gu(4), implicitWidth)
57 }
47 }
58
48
59− Image {
49+ Icon {
60− id: image
50+ id: icon
61− readonly property double leftMargin: units.gu(1)
51+ visible: name != ""
62− x: label.x + label.contentWidth + leftMargin
52+ anchors.bottom: label.baseline
63− anchors {
53+ height: units.gu(1)
64− verticalCenter: parent.verticalCenter
54+ width: height
65− }
55+ color: label.color
66 }
56 }
67 }
57 }
68
58
qml/Dash/GenericScopeView.qml+7−2
@@ -136,6 +136,7 @@ FocusScope {
136 }
136 }
137 property bool expanded: false
137 property bool expanded: false
138 readonly property string category: categoryId
138 readonly property string category: categoryId
139+ readonly property string headerLink: model.headerLink
139 readonly property var item: rendererLoader.item
140 readonly property var item: rendererLoader.item
140
141
141 function expand(expand, animate) {
142 function expand(expand, animate) {
@@ -370,10 +371,14 @@ FocusScope {
370 sectionProperty: "name"
371 sectionProperty: "name"
371 sectionDelegate: ListItems.Header {
372 sectionDelegate: ListItems.Header {
372 objectName: "dashSectionHeader" + (delegate ? delegate.category : "")
373 objectName: "dashSectionHeader" + (delegate ? delegate.category : "")
373− property var delegate: categoryView.item(delegateIndex)
374+ readonly property var delegate: categoryView.item(delegateIndex)
374 width: categoryView.width
375 width: categoryView.width
375 text: section
376 text: section
376− textColor: scopeStyle ? scopeStyle.foreground : "grey"
377+ color: scopeStyle ? scopeStyle.foreground : "grey"
378+ iconName: delegate.headerLink ? "go-next" : ""
379+ onClicked: {
380+ if (delegate.headerLink) scopeView.scope.performQuery(delegate.headerLink);
381+ }
377 }
382 }
378
383
379 pageHeader: PageHeader {
384 pageHeader: PageHeader {
tests/mocks/Unity/fake_categories.cpp+9
@@ -169,6 +169,9 @@ Categories::data(const QModelIndex& index, int role) const
169 return map;
169 return map;
170 }
170 }
171 case RoleHeaderLink:
171 case RoleHeaderLink:
172+ if (index.row() == 1) {
173+ return QString("scope://query/1");
174+ }
172 return QString();
175 return QString();
173 case RoleResults:
176 case RoleResults:
174 return QVariant::fromValue(resultsModel);
177 return QVariant::fromValue(resultsModel);
@@ -180,3 +183,9 @@ Categories::data(const QModelIndex& index, int role) const
180 }
183 }
181 }
184 }
182}
185}
186+
187+QVariant
188+Categories::data(int row, int role) const
189+{
190+ return data(index(row, 0), role);
191+}
tests/mocks/Unity/fake_categories.h+2
@@ -37,6 +37,8 @@ public:
37 Q_INVOKABLE void addSpecialCategory(QString const& categoryId, QString const& name, QString const& icon, QString const& rawTemplate, QObject* countObject) override;
37 Q_INVOKABLE void addSpecialCategory(QString const& categoryId, QString const& name, QString const& icon, QString const& rawTemplate, QObject* countObject) override;
38 Q_INVOKABLE bool overrideCategoryJson(QString const& categoryId, QString const& json) override;
38 Q_INVOKABLE bool overrideCategoryJson(QString const& categoryId, QString const& json) override;
39
39
40+ Q_INVOKABLE QVariant data(int row, int role) const;
41+
40private Q_SLOTS:
42private Q_SLOTS:
41 void countChanged();
43 void countChanged();
42
44
tests/mocks/Unity/fake_scope.cpp−5
@@ -216,8 +216,3 @@ void Scope::loadDepartment(const QString& id)
216 m_currentDeparment = id;
216 m_currentDeparment = id;
217 Q_EMIT currentDepartmentIdChanged();
217 Q_EMIT currentDepartmentIdChanged();
218}
218}
219−
220−void Scope::performQuery(const QString& query)
221−{
222− Q_UNUSED(query);
223−}
tests/mocks/Unity/fake_scope.h+1−1
@@ -64,7 +64,7 @@ public:
64 bool hasDepartments() const override;
64 bool hasDepartments() const override;
65 Q_INVOKABLE unity::shell::scopes::DepartmentInterface* getDepartment(const QString& id) override;
65 Q_INVOKABLE unity::shell::scopes::DepartmentInterface* getDepartment(const QString& id) override;
66 Q_INVOKABLE void loadDepartment(const QString& id) override;
66 Q_INVOKABLE void loadDepartment(const QString& id) override;
67− Q_INVOKABLE void performQuery(const QString& query) override;
67+ Q_SIGNAL void performQuery(const QString& query) override;
68
68
69 QVariantMap customizations() const override;
69 QVariantMap customizations() const override;
70
70
tests/qmltests/Dash/tst_GenericScopeView.qml+24
@@ -39,6 +39,10 @@ Item {
39 id: scopes
39 id: scopes
40 }
40 }
41
41
42+ SignalSpy {
43+ id: spy
44+ }
45+
42 property Item applicationManager: Item {
46 property Item applicationManager: Item {
43 signal sideStageFocusedApplicationChanged()
47 signal sideStageFocusedApplicationChanged()
44 signal mainStageFocusedApplicationChanged()
48 signal mainStageFocusedApplicationChanged()
@@ -62,6 +66,13 @@ Item {
62 waitForRendering(genericScopeView.categoryView);
66 waitForRendering(genericScopeView.categoryView);
63 }
67 }
64
68
69+ function cleanup() {
70+ genericScopeView.scope = null;
71+ spy.clear();
72+ spy.target = null;
73+ spy.signalName = "";
74+ }
75+
65 function test_isActive() {
76 function test_isActive() {
66 tryCompare(genericScopeView.scope, "isActive", false)
77 tryCompare(genericScopeView.scope, "isActive", false)
67 genericScopeView.isCurrent = true
78 genericScopeView.isCurrent = true
@@ -152,6 +163,19 @@ Item {
152 tryCompare(category2, "expanded", false);
163 tryCompare(category2, "expanded", false);
153 }
164 }
154
165
166+ function test_headerLink() {
167+ tryCompareFunction(function() { return findChild(genericScopeView, "dashSectionHeader1") != null; }, true);
168+ var header = findChild(genericScopeView, "dashSectionHeader1");
169+
170+ spy.target = genericScopeView.scope;
171+ spy.signalName = "performQuery";
172+
173+ mouseClick(header, header.width / 2, header.height / 2);
174+
175+ spy.wait();
176+ compare(spy.signalArguments[0][0], genericScopeView.scope.categories.data(1, Categories.RoleHeaderLink));
177+ }
178+
155 function test_narrow_delegate_ranges_expand() {
179 function test_narrow_delegate_ranges_expand() {
156 tryCompareFunction(function() { return findChild(genericScopeView, "dashCategory0") !== null; }, true);
180 tryCompareFunction(function() { return findChild(genericScopeView, "dashCategory0") !== null; }, true);
157 var category = findChild(genericScopeView, "dashCategory0")
181 var category = findChild(genericScopeView, "dashCategory0")