on xenial help sign in
Indicator visibility based on connection with backend service.

Approved by PS Jenkins bot, Michael Zanetti.

commit6fca6923351df54a858ab9062387aba6cb548eec authorNick Dedekind <nicholas.dedekind@gmail.com> dateSat 7 Sep 2013, 17:59 (13 years ago) parentfd712e4df569d7
31 files changed+351−125
Panel/IndicatorItem.qml+2−3 Panel/IndicatorRow.qml+19−1 Panel/Indicators.qml+17−2 Panel/Indicators/DatetimeIndicatorWidget.qml+4−2 Panel/Indicators/DefaultIndicatorWidget.qml+1 Panel/Indicators/NetworkIndicatorWidget.qml+3 Panel/Indicators/SoundIndicatorWidget.qml+1 Panel/MenuContent.qml+25−7 plugins/Unity/Indicators/CMakeLists.txt+1 plugins/Unity/Indicators/indicator.cpp−2 plugins/Unity/Indicators/indicator.h−4 plugins/Unity/Indicators/indicators.h+1−1 plugins/Unity/Indicators/indicatorsmodel.cpp−3 plugins/Unity/Indicators/indicatorsmodel.h+2−1 plugins/Unity/Indicators/plugin.cpp+2 plugins/Unity/Indicators/qml/IndicatorBase.qml−5 plugins/Unity/Indicators/qml/IndicatorWidget.qml+1 plugins/Unity/Indicators/visibleindicatorsmodel.cpp+94 plugins/Unity/Indicators/visibleindicatorsmodel.h+56 plugins/Unity/IndicatorsLegacy/qml/IndicatorWidget.qml+2−2 plugins/Utils/qsortfilterproxymodelqml.cpp+20 plugins/Utils/qsortfilterproxymodelqml.h+3 tests/mocks/Unity/Indicators/CMakeLists.txt+1 tests/mocks/Unity/Indicators/IndicatorsModel.qml+47−76 tests/mocks/Unity/Indicators/fakeplugin.cpp+2 tests/mocks/Unity/Indicators/qml/fake_menu_widget2.qml+2 tests/qmltests/CMakeLists.txt+1−1 tests/qmltests/Panel/tst_IndicatorItem.qml+2−2 tests/qmltests/Panel/tst_Indicators.qml+30−11 tests/qmltests/Panel/tst_MenuContent.qml+9−2 tests/qmltests/Panel/tst_Panel.qml+3
Panel/IndicatorItem.qml+2−3
@@ -26,13 +26,12 @@ Item {
2626 property bool highlighted: false
2727 property bool dimmed: false
2828 property var indicatorProperties: undefined
29+ property bool indicatorVisible: loader.item ? loader.item.enabled : false
2930
3031 opacity: dimmed ? 0.4 : 1
3132 Behavior on opacity { StandardAnimation {} }
3233
33− // only visible when non-empty
34− visible: loader.item != undefined && loader.status == Loader.Ready ? loader.item.enabled : false
35− width: visible ? loader.item.width : 0
34+ width: loader.item ? loader.item.width : 0
3635
3736 Loader {
3837 id: loader
Panel/IndicatorRow.qml+19−1
@@ -16,6 +16,7 @@
1616
1717import QtQuick 2.0
1818import Ubuntu.Components 0.1
19+import Unity.Indicators 0.1 as Indicators
1920import "../Components"
2021
2122Item {
@@ -25,6 +26,7 @@ Item {
2526 readonly property int currentItemIndex: currentItem ? currentItem.ownIndex : -1
2627 property alias row: row
2728 property QtObject indicatorsModel: null
29+ property var visibleIndicators: defined
2830
2931 width: units.gu(40)
3032 height: units.gu(3)
@@ -55,7 +57,8 @@ Item {
5557 Item {
5658 id: itemWrapper
5759 height: indicatorRow.height
58− width: childrenRect.width
60+ width: indicatorItem.width
61+ visible: indicatorItem.indicatorVisible
5962
6063 property int ownIndex: index
6164 property alias highlighted: indicatorItem.highlighted
@@ -70,6 +73,21 @@ Item {
7073
7174 widgetSource: model.widgetSource
7275 indicatorProperties : model.indicatorProperties
76+
77+ Component.onCompleted: {
78+ if (visibleIndicators == undefined) {
79+ visibleIndicators = {}
80+ }
81+ indicatorRow.visibleIndicators[model.identifier] = indicatorVisible;
82+ indicatorRow.visibleIndicatorsChanged();
83+ }
84+ onIndicatorVisibleChanged: {
85+ if (visibleIndicators == undefined) {
86+ visibleIndicators = {}
87+ }
88+ indicatorRow.visibleIndicators[model.identifier] = indicatorVisible;
89+ indicatorRow.visibleIndicatorsChanged();
90+ }
7391 }
7492
7593 opacity: {
Panel/Indicators.qml+17−2
@@ -180,11 +180,19 @@ Showable {
180180 clip: !indicators.fullyOpened
181181 activeHeader: indicators.state == "hint" || indicators.state == "reveal"
182182 enabled: contentEnabled
183+ visibleIndicators: indicatorRow.visibleIndicators
183184
184185 Connections {
185− target: indicatorRow
186+ property bool enableIndexChangeSignal: true
187+
188+ target: enableIndexChangeSignal ? indicatorRow : null
186189 onCurrentItemIndexChanged: {
190+ var oldActive = enableIndexChangeSignal;
191+ enableIndexChangeSignal = false;
192+
187193 menuContent.setCurrentMenuIndex(indicatorRow.currentItemIndex);
194+
195+ enableIndexChangeSignal = oldActive;
188196 }
189197 }
190198
@@ -256,9 +264,16 @@ Showable {
256264 state: indicators.state
257265
258266 Connections {
259− target: menuContent
267+ property bool enableIndexChangeSignal: true
268+
269+ target: enableIndexChangeSignal ? menuContent : null
260270 onCurrentMenuIndexChanged: {
271+ var oldActive = enableIndexChangeSignal;
272+ enableIndexChangeSignal = false;
273+
261274 indicatorRow.setCurrentItem(menuContent.currentMenuIndex);
275+
276+ enableIndexChangeSignal = oldActive;
262277 }
263278 }
264279 }
Panel/Indicators/DatetimeIndicatorWidget.qml+4−2
@@ -25,6 +25,7 @@ Indicators.IndicatorWidget {
2525 id: indicatorWidget
2626
2727 width: timeLabel.width + units.gu(1)
28+ rootMenuType: "com.canonical.indicator.root.time"
2829
2930 property alias label: timeLabel.text
3031
@@ -52,14 +53,15 @@ Indicators.IndicatorWidget {
5253
5354 onActionStateChanged: {
5455 if (action == undefined || !action.valid) {
56+ enabled = false;
5557 return;
5658 }
5759
5860 if (action.state == undefined) {
59− visible = false;
61+ enabled = false;
6062 return;
6163 }
6264
63− indicatorWidget.visible = action.state[3];
65+ enabled = action.state[3];
6466 }
6567}
Panel/Indicators/DefaultIndicatorWidget.qml+1
@@ -63,6 +63,7 @@ Indicators.IndicatorWidget {
6363
6464 onActionStateChanged: {
6565 if (action == undefined || !action.valid) {
66+ enabled = false;
6667 return;
6768 }
6869
Panel/Indicators/NetworkIndicatorWidget.qml+3
@@ -43,14 +43,17 @@ Indicators.IndicatorWidget {
4343
4444 onActionStateChanged: {
4545 if (action == undefined || !action.valid) {
46+ enabled = false;
4647 return;
4748 }
4849
4950 if (action.state == undefined) {
51+ enabled = false;
5052 connectionState = 0;
5153 return;
5254 }
5355
56+ enabled = true;
5457 connectionState = action.state[Indicators.NetworkActionState.Connection];
5558 if (connectionState == Indicators.NetworkConnection.Activated) {
5659 signalStrength = action.state[Indicators.NetworkActionState.SignalStrength];
Panel/Indicators/SoundIndicatorWidget.qml+1
@@ -22,4 +22,5 @@ import QtQuick 2.0
2222DefaultIndicatorWidget {
2323 // default the icon so we have something to show when we don't have the bus.
2424 iconSource: "image://gicon/audio-volume-high"
25+ enabled: true
2526}
Panel/MenuContent.qml+25−7
@@ -17,6 +17,7 @@
1717import QtQuick 2.0
1818import Ubuntu.Components 0.1
1919import Unity.Indicators 0.1 as Indicators
20+import Utils 0.1
2021import "../Components"
2122
2223// FIXME : We dont want to use MainView.
@@ -27,20 +28,23 @@ MainView {
2728
2829 property QtObject indicatorsModel: null
2930 property bool __contentActive: false
30− readonly property int currentMenuIndex : tabs.selectedTabIndex
31+ readonly property int currentMenuIndex : filteredIndicators.mapToSource(tabs.selectedTabIndex)
3132 backgroundColor: "#221e1c" // FIXME not in palette yet
3233 property int contentReleaseInterval: 20000
3334 property bool activeHeader: false
35+ property alias visibleIndicators: visibleIndicatorsModel.visible
3436
3537 width: units.gu(40)
3638 height: units.gu(42)
3739
3840 function setCurrentMenuIndex(index) {
39− if (currentMenuIndex !== index) {
40− if (currentMenuIndex == -1) {
41+ var filteredIndex = filteredIndicators.mapFromSource(index)
42+
43+ if (tabs.selectedTabIndex !== filteredIndex) {
44+ if (tabs.selectedTabIndex == -1) {
4145 tabs.tabBar.animate = false;
4246 }
43− tabs.selectedTabIndex = index;
47+ tabs.selectedTabIndex = filteredIndex;
4448 tabs.tabBar.animate = true;
4549 }
4650 }
@@ -61,6 +65,20 @@ MainView {
6165 tabs.tabBar.alwaysSelectionMode = activeHeader;
6266 }
6367
68+ SortFilterProxyModel {
69+ id: filteredIndicators
70+ model: visibleIndicatorsModel
71+ dynamicSortFilter: true
72+
73+ filterRole: Indicators.IndicatorsModelRole.IsVisible
74+ filterRegExp: RegExp("^true$")
75+ }
76+
77+ Indicators.VisibleIndicatorsModel {
78+ id: visibleIndicatorsModel
79+ model: indicatorsModel
80+ }
81+
6482 Tabs {
6583 id: tabs
6684 objectName: "tabs"
@@ -69,8 +87,8 @@ MainView {
6987
7088 Repeater {
7189 id: repeater
72− model: indicatorsModel
73− objectName: "menus"
90+ model: filteredIndicators
91+ objectName: "tabsRepeater"
7492
7593 // FIXME: This is needed because tabs dont handle repeaters well.
7694 // Due to the child ordering happening after child insertion.
@@ -114,7 +132,7 @@ MainView {
114132 item[pName] = indicatorProperties[pName]
115133 }
116134 }
117− if (contentActive && menus.visible) {
135+ if (contentActive && tabs.visible) {
118136 item.start()
119137 }
120138 }
plugins/Unity/Indicators/CMakeLists.txt+1
@@ -34,6 +34,7 @@ set(IndicatorsQML_SOURCES
3434 rootactionstate.cpp
3535 unitymenumodelcache.cpp
3636 unitymenumodelstack.cpp
37+ visibleindicatorsmodel.cpp
3738)
3839add_definitions(-DUNITYINDICATORS_LIBRARY)
3940
plugins/Unity/Indicators/indicator.cpp−2
@@ -51,7 +51,6 @@ void Indicator::init(const QString& busName, const QSettings& settings)
5151 }
5252 }
5353
54−
5554 QVariantMap properties;
5655 properties.clear();
5756 properties.insert("busType", 1);
@@ -87,7 +86,6 @@ void Indicator::setPosition(int position)
8786 }
8887}
8988
90−
9189QVariant Indicator::indicatorProperties() const
9290{
9391 return m_properties;
plugins/Unity/Indicators/indicator.h−4
@@ -29,10 +29,6 @@
2929class UNITYINDICATORS_EXPORT Indicator : public QObject
3030{
3131 Q_OBJECT
32− Q_PROPERTY(QString identifier READ identifier NOTIFY identifierChanged)
33− Q_PROPERTY(int position READ position NOTIFY positionChanged)
34− Q_PROPERTY(QVariant indicatorProperties READ indicatorProperties NOTIFY indicatorPropertiesChanged)
35−
3632public:
3733 typedef QSharedPointer<Indicator> Ptr;
3834
plugins/Unity/Indicators/indicators.h+1−1
@@ -79,7 +79,7 @@ public:
7979 WidgetSource,
8080 PageSource,
8181 IndicatorProperties,
82− IsValid
82+ IsVisible
8383 };
8484
8585 IndicatorsModelRole(QObject*parent=0):QObject(parent) {}
plugins/Unity/Indicators/indicatorsmodel.cpp−3
@@ -206,7 +206,6 @@ QHash<int, QByteArray> IndicatorsModel::roleNames() const
206206 roles[IndicatorsModelRole::WidgetSource] = "widgetSource";
207207 roles[IndicatorsModelRole::PageSource] = "pageSource";
208208 roles[IndicatorsModelRole::IndicatorProperties] = "indicatorProperties";
209− roles[IndicatorsModelRole::IsValid] = "isValid";
210209 }
211210 return roles;
212211}
@@ -269,8 +268,6 @@ QVariant IndicatorsModel::data(const QModelIndex &index, int role) const
269268 return QVariant(indicator->indicatorProperties());
270269 }
271270 break;
272− case IndicatorsModelRole::IsValid:
273− return (indicator ? true : false);
274271 case IndicatorsModelRole::Title:
275272 case IndicatorsModelRole::Description:
276273 case IndicatorsModelRole::WidgetSource:
plugins/Unity/Indicators/indicatorsmodel.h+2−1
@@ -44,7 +44,7 @@ public:
4444 Q_INVOKABLE void load();
4545 Q_INVOKABLE void unload();
4646
47− Q_INVOKABLE QVariant data(int row, int role = Qt::DisplayRole) const;
47+ Q_INVOKABLE QVariant data(int row, int role) const;
4848
4949 /* QAbstractItemModel */
5050 QHash<int, QByteArray> roleNames() const;
@@ -56,6 +56,7 @@ public:
5656 void setIndicatorData(const QVariant& data);
5757 QVariant indicatorData() const;
5858
59+
5960Q_SIGNALS:
6061 void countChanged();
6162 void indicatorDataChanged(const QVariant& data);
plugins/Unity/Indicators/plugin.cpp+2
@@ -32,6 +32,7 @@
3232#include "rootactionstate.h"
3333#include "unitymenumodelcache.h"
3434#include "unitymenumodelstack.h"
35+#include "visibleindicatorsmodel.h"
3536
3637static QObject* menuModelCacheSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
3738 Q_UNUSED(engine);
@@ -47,6 +48,7 @@ void Indicators2Plugin::registerTypes(const char *uri)
4748 qmlRegisterType<UnityMenuModelStack>(uri, 0, 1, "UnityMenuModelStack");
4849 qmlRegisterType<RootActionState>(uri, 0, 1, "RootActionState");
4950 qmlRegisterType<ModelPrinter>(uri, 0, 1, "ModelPrinter");
51+ qmlRegisterType<VisibleIndicatorsModel>(uri, 0, 1, "VisibleIndicatorsModel");
5052
5153 qmlRegisterSingletonType<UnityMenuModelCache>(uri, 0, 1, "UnityMenuModelCache", menuModelCacheSingleton);
5254
plugins/Unity/Indicators/qml/IndicatorBase.qml−5
@@ -24,8 +24,6 @@ import Unity.Indicators 0.1 as Indicators
2424Item {
2525 id: indicatorItem
2626
27− // FIXME : should be disabled until bus available when we have desktop indicators
28− // for now, disable when we dont habe the correct profile.
2927 enabled: menuObjectPaths.hasOwnProperty(device)
3028
3129 //const
@@ -39,9 +37,6 @@ Item {
3937
4038 property string deviceMenuObjectPath: menuObjectPaths.hasOwnProperty(device) ? menuObjectPaths[device] : ""
4139
42− signal actionGroupUpdated()
43− signal modelUpdated()
44−
4540 property alias menuModel: cachedModel.model
4641
4742 CachedUnityMenuModel {
plugins/Unity/Indicators/qml/IndicatorWidget.qml+1
@@ -24,6 +24,7 @@ IndicatorBase {
2424 id: indicatorWidget
2525
2626 active: true
27+ enabled: false
2728 property int iconSize: height - units.gu(0.5)
2829
2930 property var actionState: Indicators.RootActionState {
plugins/Unity/Indicators/visibleindicatorsmodel.cppnew file+94
@@ -0,0 +1,94 @@
1+/*
2+ * Copyright (C) 2012, 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+// self
18+#include "visibleindicatorsmodel.h"
19+#include "indicators.h"
20+
21+VisibleIndicatorsModel::VisibleIndicatorsModel(QObject *parent)
22+ : QIdentityProxyModel(parent),
23+ m_inserting(false)
24+{
25+ QObject::connect(this, SIGNAL(rowsAboutToBeInserted(QModelIndex, int, int)), this, SLOT(onBeginRowInserted(QModelIndex, int, int)));
26+ QObject::connect(this, SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(onRowInserted(QModelIndex, int, int)));
27+}
28+
29+QHash<int, QByteArray> VisibleIndicatorsModel::roleNames() const
30+{
31+ static QHash<int, QByteArray> roles;
32+ if (roles.isEmpty())
33+ {
34+ roles[IndicatorsModelRole::Identifier] = "identifier";
35+ roles[IndicatorsModelRole::Position] = "position";
36+ roles[IndicatorsModelRole::Title] = "title";
37+ roles[IndicatorsModelRole::Description] = "description";
38+ roles[IndicatorsModelRole::WidgetSource] = "widgetSource";
39+ roles[IndicatorsModelRole::PageSource] = "pageSource";
40+ roles[IndicatorsModelRole::IndicatorProperties] = "indicatorProperties";
41+ roles[IndicatorsModelRole::IsVisible] = "isVisible";
42+ }
43+ return roles;
44+}
45+
46+void VisibleIndicatorsModel::setSourceModel(QAbstractItemModel *model)
47+{
48+ if (sourceModel() != model) {
49+ QIdentityProxyModel::setSourceModel(model);
50+ Q_EMIT modelChanged();
51+ }
52+}
53+
54+QVariantMap VisibleIndicatorsModel::visible() const
55+{
56+ return m_visible;
57+}
58+
59+void VisibleIndicatorsModel::onBeginRowInserted(const QModelIndex&, int, int)
60+{
61+ m_inserting = true;
62+}
63+
64+void VisibleIndicatorsModel::onRowInserted(const QModelIndex&, int, int)
65+{
66+ m_inserting = false;
67+}
68+
69+void VisibleIndicatorsModel::setVisible(const QVariantMap& visible)
70+{
71+ if (m_visible != visible) {
72+ m_visible = visible;
73+ Q_EMIT visibleChanged();
74+
75+ // need to tell the view that the visible data has changed.
76+ if (!m_inserting && rowCount() > 0) {
77+ Q_EMIT dataChanged(index(0, 0), index(rowCount() - 1, 0), QVector<int>() << IndicatorsModelRole::IsVisible);
78+ }
79+ }
80+}
81+
82+QVariant VisibleIndicatorsModel::data(const QModelIndex &index, int role) const
83+{
84+ if (role != IndicatorsModelRole::IsVisible) {
85+ return QIdentityProxyModel::data(index, role);
86+ }
87+
88+ if (!index.isValid()) {
89+ return false;
90+ }
91+
92+ QString ident = QIdentityProxyModel::data(index, IndicatorsModelRole::Identifier).toString();
93+ return m_visible.value(ident, false).toBool();
94+}
plugins/Unity/Indicators/visibleindicatorsmodel.hnew file+56
@@ -0,0 +1,56 @@
1+/*
2+ * Copyright (C) 2012, 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+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+#ifndef VISIBLEINDICATORSMODEL_H
21+#define VISIBLEINDICATORSMODEL_H
22+
23+#include <QIdentityProxyModel>
24+
25+class VisibleIndicatorsModel : public QIdentityProxyModel
26+{
27+ Q_OBJECT
28+
29+ Q_PROPERTY(QAbstractItemModel* model READ sourceModel WRITE setSourceModel NOTIFY modelChanged)
30+ Q_PROPERTY(QVariantMap visible READ visible WRITE setVisible NOTIFY visibleChanged)
31+
32+public:
33+ explicit VisibleIndicatorsModel(QObject *parent = 0);
34+
35+ virtual void setSourceModel(QAbstractItemModel *model);
36+ virtual QHash<int, QByteArray> roleNames() const;
37+ virtual QVariant data(const QModelIndex &index, int role) const;
38+
39+ QVariantMap visible() const;
40+ void setVisible(const QVariantMap& visible);
41+
42+public Q_SLOTS:
43+ void onBeginRowInserted(const QModelIndex&, int start, int end);
44+ void onRowInserted(const QModelIndex&, int start, int end);
45+
46+Q_SIGNALS:
47+ void totalCountChanged();
48+ void modelChanged();
49+ void visibleChanged();
50+
51+private:
52+ QVariantMap m_visible;
53+ bool m_inserting;
54+};
55+
56+#endif // VISIBLEINDICATORSMODEL_H
plugins/Unity/IndicatorsLegacy/qml/IndicatorWidget.qml+2−2
@@ -23,7 +23,7 @@ import Unity.IndicatorsLegacy 0.1 as Indicators
2323IndicatorBase {
2424 id: indicatorWidget
2525
26−// enabled: false // FIXME : should be disabled until bus available when we have desktop indicators
26+ enabled: false
2727 property var action: undefined
2828 property bool started: (busType != 0) && (busName != "") && (deviceMenuObjectPath != "")
2929 property int iconSize: height - units.gu(0.5)
@@ -40,7 +40,6 @@ IndicatorBase {
4040 actionGroup.stop();
4141 }
4242 }
43− onActionChanged: actionStateChanged()
4443 onActionGroupUpdated: update_state()
4544 onModelUpdated: update_state()
4645
@@ -57,6 +56,7 @@ IndicatorBase {
5756
5857 if (extra.canonical_type === rootMenuType) {
5958 action = actionGroup.action(proxyModel.data(0, Indicators.FlatMenuProxyModelRole.Action));
59+ actionStateChanged();
6060 }
6161 }
6262
plugins/Utils/qsortfilterproxymodelqml.cpp+20
@@ -121,3 +121,23 @@ QSortFilterProxyModelQML::findFirst(int role, const QVariant& value) const
121121 return -1;
122122 }
123123}
124+
125+int
126+QSortFilterProxyModelQML::mapFromSource(int row)
127+{
128+ if (sourceModel() != NULL) {
129+ return QSortFilterProxyModel::mapFromSource(sourceModel()->index(row, 0)).row();
130+ } else {
131+ return -1;
132+ }
133+}
134+
135+int
136+QSortFilterProxyModelQML::mapToSource(int row)
137+{
138+ if (sourceModel() != NULL) {
139+ return QSortFilterProxyModel::mapToSource(index(row, 0)).row();
140+ } else {
141+ return -1;
142+ }
143+}
plugins/Utils/qsortfilterproxymodelqml.h+3
@@ -45,6 +45,9 @@ public:
4545 void setModel(QAbstractItemModel *model);
4646 void setInvertMatch(bool invertMatch);
4747
48+ Q_INVOKABLE int mapFromSource(int row);
49+ Q_INVOKABLE int mapToSource(int row);
50+
4851Q_SIGNALS:
4952 void totalCountChanged();
5053 void countChanged();
tests/mocks/Unity/Indicators/CMakeLists.txt+1
@@ -13,6 +13,7 @@ set(IndicatorsFakeQml_SOURCES
1313 fakeplugin.cpp
1414 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/indicators.h
1515 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/menucontentactivator.cpp
16+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/visibleindicatorsmodel.cpp
1617)
1718
1819set(IndicatorsFakeQml_RESOURCES
tests/mocks/Unity/Indicators/IndicatorsModel.qml+47−76
@@ -23,82 +23,53 @@ ListModel {
2323
2424 function load() {}
2525
26− ListElement {
27− identifier: "indicator-fake1";
28− priority: 0
29− title: "Menu1";
30− description: "";
31− widgetSource: "qrc:/tests/indciators/qml/fake_menu_widget1.qml";
32− pageSource: "qrc:/tests/indciators/qml/fake_menu_page1.qml";
33− indicatorProperties: "";
34− isValid: "";
35− }
36− ListElement {
37− identifier: "indicator-fake2";
38− priority: 1
39− title: "Menu2";
40− description: "";
41− widgetSource: "qrc:/tests/indciators/qml/fake_menu_widget2.qml";
42− pageSource: "qrc:/tests/indciators/qml/fake_menu_page2.qml";
43− indicatorProperties: "";
44− isValid: "";
45− }
46− ListElement {
47− identifier: "indicator-fake3";
48− priority: 2
49− title: "Menu3";
50− description: "";
51− widgetSource: "qrc:/tests/indciators/qml/fake_menu_widget3.qml";
52− pageSource: "qrc:/tests/indciators/qml/fake_menu_page3.qml";
53− indicatorProperties: "";
54− isValid: "";
55− }
56− ListElement {
57− identifier: "indicator-fake4";
58− priority: 3
59− title: "Menu4";
60− description: "";
61− widgetSource: "qrc:/tests/indciators/qml/fake_menu_widget4.qml";
62− pageSource: "qrc:/tests/indciators/qml/fake_menu_page4.qml";
63− indicatorProperties: "";
64− isValid: "";
65− }
66− ListElement {
67− identifier: "indicator-fake5";
68− priority: 4
69− title: "Menu5";
70− description: "";
71− widgetSource: "qrc:/tests/indciators/qml/fake_menu_widget5.qml";
72− pageSource: "qrc:/tests/indciators/qml/fake_menu_page5.qml";
73− indicatorProperties: "";
74− isValid: "";
75− }
26+ // Need to do this dynamically.
27+ // Apparently ListModels dont order roles visually when using ListElement
28+ // which throws off the filter for non-visible indicators.
29+ Component.onCompleted: {
30+ append({ "identifier": "indicator-fake1",
31+ "priority": 0,
32+ "title": "Menu1",
33+ "description": "",
34+ "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget1.qml",
35+ "pageSource": "qrc:/tests/indciators/qml/fake_menu_page1.qml",
36+ "indicatorProperties": ""
37+ });
7638
77− function data(row, role) {
78− if (role == Indicators.IndicatorsModelRole.Identifier) {
79− return get(row).identifier;
80− }
81− else if (role == Indicators.IndicatorsModelRole.Priority) {
82− return get(row).priority
83− }
84− else if (role == Indicators.IndicatorsModelRole.Title) {
85− return get(row).title
86− }
87− else if (role == Indicators.IndicatorsModelRole.Description) {
88− return get(row).description
89− }
90− else if (role == Indicators.IndicatorsModelRole.WidgetSource) {
91− return get(row).widgetSource
92− }
93− else if (role == Indicators.IndicatorsModelRole.PageSource) {
94− return get(row).pageSource
95− }
96− else if (role == Indicators.IndicatorsModelRole.IndicatorProperties) {
97− return get(row).indicatorProperties
98− }
99− else if (role == Indicators.IndicatorsModelRole.IsValid) {
100− return get(row).isValid
101− }
102− }
39+ append({ "identifier": "indicator-fake2",
40+ "priority": 1,
41+ "title": "Menu2",
42+ "description": "",
43+ "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget2.qml",
44+ "pageSource": "qrc:/tests/indciators/qml/fake_menu_page2.qml",
45+ "indicatorProperties": ""
46+ });
47+
48+ append({ "identifier": "indicator-fake3",
49+ "priority": 2,
50+ "title": "Menu3",
51+ "description": "",
52+ "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget3.qml",
53+ "pageSource": "qrc:/tests/indciators/qml/fake_menu_page3.qml",
54+ "indicatorProperties": ""
55+ });
10356
57+ append({ "identifier": "indicator-fake4",
58+ "priority": 3,
59+ "title": "Menu4",
60+ "description": "",
61+ "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget4.qml",
62+ "pageSource": "qrc:/tests/indciators/qml/fake_menu_page4.qml",
63+ "indicatorProperties": ""
64+ });
65+
66+ append({ "identifier": "indicator-fake5",
67+ "priority": 4,
68+ "title": "Menu5",
69+ "description": "",
70+ "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget5.qml",
71+ "pageSource": "qrc:/tests/indciators/qml/fake_menu_page5.qml",
72+ "indicatorProperties": ""
73+ });
74+ }
10475}
tests/mocks/Unity/Indicators/fakeplugin.cpp+2
@@ -25,12 +25,14 @@
2525// local
2626#include "indicators.h"
2727#include "menucontentactivator.h"
28+#include "visibleindicatorsmodel.h"
2829
2930void IndicatorsFakePlugin::registerTypes(const char * uri)
3031{
3132 Q_INIT_RESOURCE(indicators_fake);
3233
3334 qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
35+ qmlRegisterType<VisibleIndicatorsModel>(uri, 0, 1, "VisibleIndicatorsModel");
3436
3537 qmlRegisterUncreatableType<MenuContentState>(uri, 0, 1, "MenuContentState", "Can't create MenuContentState class");
3638 qmlRegisterUncreatableType<ActionState>(uri, 0, 1, "ActionState", "Can't create ActionState class");
tests/mocks/Unity/Indicators/qml/fake_menu_widget2.qml+2
@@ -20,4 +20,6 @@ Rectangle {
2020 width: 40
2121 height: 40
2222 color : "yellow"
23+
24+ enabled: false
2325}
tests/qmltests/CMakeLists.txt+1−1
@@ -66,7 +66,7 @@ add_qml_test(Launcher Launcher IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltes
6666add_qml_test(Notifications Notifications IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_SOURCE_DIR}/tests/mocks)
6767add_qml_test(Panel IndicatorRow)
6868add_qml_test(Panel Indicators IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
69−add_qml_test(Panel MenuContent)
69+add_qml_test(Panel MenuContent IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
7070add_qml_test(Panel Panel IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
7171add_qml_test(Panel SearchIndicator)
7272add_qml_test(SideStage SideStage IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS}
tests/qmltests/Panel/tst_IndicatorItem.qml+2−2
@@ -53,9 +53,9 @@ Rectangle {
5353 }
5454
5555 function test_empty() {
56− compare(indicatorItem.visible, false, "IndicatorItem should not be visible.");
56+ compare(indicatorItem.indicatorVisible, false, "IndicatorItem should not be visible.");
5757 indicatorItem.widgetSource = "qrc:/tests/indciators/qml/fake_menu_widget1.qml";
58− tryCompare(indicatorItem, "visible", true);
58+ tryCompare(indicatorItem, "indicatorVisible", true);
5959 }
6060 }
6161}
tests/qmltests/Panel/tst_Indicators.qml+30−11
@@ -100,26 +100,29 @@ Item {
100100 {
101101 // tests changing the lateral position of the revealer activates the correct indicator items.
102102
103− var indicator_row = findChild(indicators, "indicatorRow")
104− var row_repeater = findChild(indicators, "rowRepeater")
103+ var indicatorRow = findChild(indicators, "indicatorRow")
104+ var rowRepeater = findChild(indicators, "rowRepeater")
105105
106− for (var i = 0; i < row_repeater.count; i++) {
107− var indicator_item = row_repeater.itemAt(i);
106+ for (var i = 0; i < rowRepeater.count; i++) {
107+ var indicatorItem = rowRepeater.itemAt(i);
108108
109− var indicator_position = indicators.mapFromItem(indicator_item,
110− indicator_item.width/2, indicator_item.height/2)
109+ if (!indicatorItem.visible)
110+ continue;
111+
112+ var indicatorPosition = indicators.mapFromItem(indicatorItem,
113+ indicatorItem.width/2, indicatorItem.height/2)
111114
112115 touchFlick(indicators,
113− indicator_position.x, indicator_position.y,
114− indicator_position.x, indicators.openedHeight * 0.4,
116+ indicatorPosition.x, indicatorPosition.y,
117+ indicatorPosition.x, indicators.openedHeight * 0.4,
115118 true /* beginTouch */, false /* endTouch */)
116119
117− compare(indicator_row.currentItem, indicator_item,
120+ compare(indicatorRow.currentItem, indicatorItem,
118121 "Incorrect item activated at position " + i);
119122
120123 touchFlick(indicators,
121− indicator_position.x, indicators.openedHeight * 0.4,
122− indicator_position.x, indicator_position.y,
124+ indicatorPosition.x, indicators.openedHeight * 0.4,
125+ indicatorPosition.x, indicatorPosition.y,
123126 false /* beginTouch */, true /* endTouch */)
124127
125128 // wait until fully closed
@@ -158,5 +161,21 @@ Item {
158161 compare(indicators.fullyOpened, true);
159162 }
160163
164+ function test_row_visible_menuContent_visible_data() { return [
165+ {tag: "visible", index: 0, name: "indicator-fake1", visible: true },
166+ {tag: "invisible", index: 1, name: "indicator-fake2", visible: false }]
167+ }
168+
169+ function test_row_visible_menuContent_visible(data) {
170+ var indicatorTabs = findChild(indicators, "tabs");
171+ var rowRepeater = findChild(indicators, "rowRepeater");
172+
173+ var indicatorItem = rowRepeater.itemAt(data.index);
174+ tryCompareFunction(function() { return indicatorItem.width > 0}, true);
175+ tryCompare(indicatorItem, "visible", data.visible);
176+
177+ var indicatorTab = findChild(indicatorTabs, data.name)
178+ tryCompareFunction(function() { return indicatorTab !== undefined }, data.visible);
179+ }
161180 }
162181}
tests/qmltests/Panel/tst_MenuContent.qml+9−2
@@ -48,8 +48,15 @@ Item {
4848 id: menuContent
4949 indicatorsModel: indicatorsModel
5050 contentReleaseInterval: 50
51−
5251 height: parent.height - 50
52+
53+ visibleIndicators: {
54+ 'indicator-fake1': true,
55+ 'indicator-fake2': true,
56+ 'indicator-fake3': true,
57+ 'indicator-fake4': true,
58+ 'indicator-fake5': true
59+ }
5360 }
5461
5562 Rectangle {
@@ -134,7 +141,7 @@ Item {
134141 var menuIndex = i%menuCount;
135142
136143 activate_content(menuIndex);
137− testTabObjectName = indicatorsModel.data(menuIndex, Indicators.IndicatorsModelRole.Identifier);
144+ testTabObjectName = indicatorsModel.get(menuIndex).identifier;
138145 compare(tabs.selectedTabIndex, menuIndex, "Current tab index does not match selected tab index");
139146 tryCompareFunction(selected_tab_equals_test_tab, true);
140147 }
tests/qmltests/Panel/tst_Panel.qml+3
@@ -159,6 +159,9 @@ Item {
159159 var indicatorItem = get_indicator_item(i);
160160 verify(indicatorItem != undefined);
161161
162+ if (!indicatorItem.visible)
163+ continue;
164+
162165 var indicatorItemCoord = get_indicator_item_position(i);
163166
164167 touchPress(panel,