on xenial help sign in
remove qml ownership confusion for caching unitymenumodels Fixes: 1368856

Approved by: Albert Astals Cid

commit41cc2253f046d6b07db087901c9d0acf64e7e2ce authorNick Dedekind <nick.dedekind@canonical.com> dateThu 30 Oct 2014, 10:49 (12 years ago) parent9c6d98e9f4cd46
66 files changed+933−758
plugins/AccountsService/AccountsService.qmltypes+2 plugins/Dash/Dash.qmltypes+3 plugins/LightDM/LightDM.qmltypes+1 plugins/Ubuntu/Payments/Payments.qmltypes+1 plugins/Unity/DashCommunicator/DashCommunicator.qmltypes+16−3 plugins/Unity/Indicators/CMakeLists.txt+1 plugins/Unity/Indicators/Indicators.qmltypes+10−7 plugins/Unity/Indicators/plugin.cpp+8−2 plugins/Unity/Indicators/plugin.h+1−1 plugins/Unity/Indicators/sharedunitymenumodel.cpp+87 plugins/Unity/Indicators/sharedunitymenumodel.h+66 plugins/Unity/Indicators/unitymenumodelcache.cpp+27−12 plugins/Unity/Indicators/unitymenumodelcache.h+13−7 plugins/Unity/Launcher/Launcher.qmltypes+17−12 plugins/Unity/Session/Session.qmltypes+10 plugins/Utils/Utils.qmltypes+6 qml/Greeter/Clock.qml+9−9 qml/Panel/Indicators/CachedUnityMenuModel.qml−39 qml/Panel/Indicators/IndicatorBase.qml+2−2 tests/mocks/AccountsService/AccountsService.qmltypes+2 tests/mocks/LightDM/LightDM.qmltypes+1 tests/mocks/QMenuModel/QMenuModel.qmltypes+1−1 tests/mocks/QMenuModel/unitymenumodel.cpp+1−2 tests/mocks/QMenuModel/unitymenumodel.h+6−2 tests/mocks/Ubuntu/Payments/Payments.qmltypes+2 tests/mocks/Ubuntu/Telephony/Telephony.qmltypes+2−1 tests/mocks/Unity/Application/Application.qmltypes+13 tests/mocks/Unity/DashCommunicator/DashCommunicator.qmltypes+2−2 tests/mocks/Unity/Indicators/CMakeLists.txt+3−10 tests/mocks/Unity/Indicators/FakeMenuPage.qml−27 tests/mocks/Unity/Indicators/Indicators.qmltypes+41−11 tests/mocks/Unity/Indicators/IndicatorsModel.qml+143−35 tests/mocks/Unity/Indicators/RootActionState.qml+17−9 tests/mocks/Unity/Indicators/fakeindicatorsmodel.cpp+50−19 tests/mocks/Unity/Indicators/fakeindicatorsmodel.h+8−2 tests/mocks/Unity/Indicators/fakeplugin.cpp+8−4 tests/mocks/Unity/Indicators/fakeunitymenumodelcache.cpp+57 tests/mocks/Unity/Indicators/fakeunitymenumodelcache.h+49 tests/mocks/Unity/Indicators/indicators_fake.qrc−14 tests/mocks/Unity/Indicators/qml/fake_menu_page1.qml−35 tests/mocks/Unity/Indicators/qml/fake_menu_page2.qml−35 tests/mocks/Unity/Indicators/qml/fake_menu_page3.qml−35 tests/mocks/Unity/Indicators/qml/fake_menu_page4.qml−35 tests/mocks/Unity/Indicators/qml/fake_menu_page5.qml−35 tests/mocks/Unity/Indicators/qml/fake_menu_widget1.qml−23 tests/mocks/Unity/Indicators/qml/fake_menu_widget2.qml−23 tests/mocks/Unity/Indicators/qml/fake_menu_widget3.qml−23 tests/mocks/Unity/Indicators/qml/fake_menu_widget4.qml−23 tests/mocks/Unity/Indicators/qml/fake_menu_widget5.qml−23 tests/mocks/Unity/Indicators/qmldir−1 tests/mocks/Unity/Launcher/Launcher.qmltypes+13 tests/mocks/Unity/Unity.qmltypes+32 tests/plugins/Unity/Indicators/CMakeLists.txt+1 tests/plugins/Unity/Indicators/sharedunitymenumodeltest.cpp+102 tests/qmltests/CMakeLists.txt+7−8 tests/qmltests/Greeter/tst_Clock.qml+51−34 tests/qmltests/Panel/Indicators/tst_CachedUnityMenuModel.qml−137 tests/qmltests/Panel/Indicators/tst_DefaultIndicatorPage.qml+16−19 tests/qmltests/Panel/Indicators/tst_DefaultIndicatorWidget.qml−8 tests/qmltests/Panel/tst_IndicatorItem.qml+1−1 tests/qmltests/Panel/tst_IndicatorRow.qml+17−19 tests/qmltests/Panel/tst_Indicators.qml+1 tests/qmltests/Panel/tst_MenuContent.qml−8 tests/qmltests/tst_Shell.qml+2 tests/qmltests/tst_ShellWithPin.qml+2 tests/qmltests/tst_TabletShell.qml+2
plugins/AccountsService/AccountsService.qmltypes+2
@@ -23,6 +23,8 @@ Module {
2323 }
2424 Property { name: "user"; type: "string" }
2525 Property { name: "demoEdges"; type: "bool" }
26+ Property { name: "enableLauncherWhileLocked"; type: "bool"; isReadonly: true }
27+ Property { name: "enableIndicatorsWhileLocked"; type: "bool"; isReadonly: true }
2628 Property { name: "backgroundFile"; type: "string"; isReadonly: true }
2729 Property { name: "statsWelcomeScreen"; type: "bool"; isReadonly: true }
2830 Property { name: "passwordDisplayHint"; type: "PasswordDisplayHint"; isReadonly: true }
plugins/Dash/Dash.qmltypes+3
@@ -40,9 +40,12 @@ Module {
4040 Property { name: "forceNoClip"; type: "bool" }
4141 Property { name: "stickyHeaderHeight"; type: "int"; isReadonly: true }
4242 Property { name: "headerItemShownHeight"; type: "double"; isReadonly: true }
43+ Property { name: "cacheBuffer"; type: "double" }
4344 Signal { name: "headerChanged" }
4445 Method { name: "positionAtBeginning" }
4546 Method { name: "showHeader" }
47+ Method { name: "firstCreatedIndex"; type: "int" }
48+ Method { name: "createdItemCount"; type: "int" }
4649 Method {
4750 name: "item"
4851 type: "QQuickItem*"
plugins/LightDM/LightDM.qmltypes+1
@@ -37,6 +37,7 @@ Module {
3737 Signal { name: "isActiveChanged" }
3838 Signal { name: "isAuthenticatedChanged" }
3939 Signal { name: "showGreeter" }
40+ Signal { name: "hideGreeter" }
4041 Signal {
4142 name: "requestAuthenticationUser"
4243 Parameter { name: "user"; type: "string" }
plugins/Ubuntu/Payments/Payments.qmltypes+1
@@ -37,6 +37,7 @@ Module {
3737 Parameter { name: "error"; type: "string" }
3838 }
3939 Signal { name: "purchaseCompleted" }
40+ Signal { name: "purchaseCancelled" }
4041 Method { name: "start" }
4142 }
4243}
plugins/Unity/DashCommunicator/DashCommunicator.qmltypes+16−3
@@ -9,14 +9,14 @@ import QtQuick.tooling 1.1
99Module {
1010 Component {
1111 name: "DashCommunicator"
12− prototype: "QObject"
12+ prototype: "QThread"
1313 exports: ["Unity.DashCommunicator/DashCommunicator 0.1"]
1414 exportMetaObjectRevisions: [0]
1515 Method {
1616 name: "setCurrentScope"
1717 Parameter { name: "scopeId"; type: "string" }
1818 Parameter { name: "animate"; type: "bool" }
19− Parameter { name: "reset"; type: "bool" }
19+ Parameter { name: "isSwipe"; type: "bool" }
2020 }
2121 }
2222 Component {
@@ -28,7 +28,20 @@ Module {
2828 name: "setCurrentScopeRequested"
2929 Parameter { name: "scopeId"; type: "string" }
3030 Parameter { name: "animate"; type: "bool" }
31− Parameter { name: "reset"; type: "bool" }
31+ Parameter { name: "isSwipe"; type: "bool" }
32+ }
33+ }
34+ Component {
35+ name: "QThread"
36+ prototype: "QObject"
37+ Signal { name: "started" }
38+ Signal { name: "finished" }
39+ Method {
40+ name: "start"
41+ Parameter { type: "Priority" }
3242 }
43+ Method { name: "start" }
44+ Method { name: "terminate" }
45+ Method { name: "quit" }
3346 }
3447}
plugins/Unity/Indicators/CMakeLists.txt+1
@@ -24,6 +24,7 @@ set(IndicatorsQML_SOURCES
2424 modelprinter.cpp
2525 plugin.cpp
2626 rootactionstate.cpp
27+ sharedunitymenumodel.cpp
2728 unitymenumodelcache.cpp
2829 unitymenumodelstack.cpp
2930 visibleindicatorsmodel.cpp
plugins/Unity/Indicators/Indicators.qmltypes+10−7
@@ -209,6 +209,16 @@ Module {
209209 Signal { name: "updated" }
210210 Signal { name: "indexChanged" }
211211 }
212+ Component {
213+ name: "SharedUnityMenuModel"
214+ prototype: "QObject"
215+ exports: ["Unity.Indicators/SharedUnityMenuModel 0.1"]
216+ exportMetaObjectRevisions: [0]
217+ Property { name: "busName"; type: "QByteArray" }
218+ Property { name: "menuObjectPath"; type: "QByteArray" }
219+ Property { name: "actions"; type: "QVariantMap" }
220+ Property { name: "model"; type: "UnityMenuModel"; isReadonly: true; isPointer: true }
221+ }
212222 Component {
213223 name: "UnityMenuModelCache"
214224 prototype: "QObject"
@@ -216,13 +226,6 @@ Module {
216226 isCreatable: false
217227 isSingleton: true
218228 exportMetaObjectRevisions: [0]
219− Method {
220− name: "model"
221− type: "UnityMenuModel*"
222− Parameter { name: "bus"; type: "QByteArray" }
223− Parameter { name: "path"; type: "QByteArray" }
224− Parameter { name: "actions"; type: "QVariantMap" }
225− }
226229 Method {
227230 name: "contains"
228231 type: "bool"
plugins/Unity/Indicators/plugin.cpp+8−2
@@ -30,18 +30,23 @@
3030#include "menucontentactivator.h"
3131#include "modelprinter.h"
3232#include "rootactionstate.h"
33+#include "sharedunitymenumodel.h"
3334#include "unitymenumodelcache.h"
3435#include "unitymenumodelstack.h"
3536#include "visibleindicatorsmodel.h"
3637
38+#include <unitymenumodel.h>
39+
3740static QObject* menuModelCacheSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
3841 Q_UNUSED(engine);
3942 Q_UNUSED(scriptEngine);
40− return new UnityMenuModelCache;
43+ return UnityMenuModelCache::singleton();
4144}
4245
43−void Indicators2Plugin::registerTypes(const char *uri)
46+void IndicatorsPlugin::registerTypes(const char *uri)
4447{
48+ qRegisterMetaType<UnityMenuModel*>("UnityMenuModel*");
49+
4550 qmlRegisterType<IndicatorsManager>(uri, 0, 1, "IndicatorsManager");
4651 qmlRegisterType<IndicatorsModel>(uri, 0, 1, "IndicatorsModel");
4752 qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
@@ -49,6 +54,7 @@ void Indicators2Plugin::registerTypes(const char *uri)
4954 qmlRegisterType<RootActionState>(uri, 0, 1, "RootActionState");
5055 qmlRegisterType<ModelPrinter>(uri, 0, 1, "ModelPrinter");
5156 qmlRegisterType<VisibleIndicatorsModel>(uri, 0, 1, "VisibleIndicatorsModel");
57+ qmlRegisterType<SharedUnityMenuModel>(uri, 0, 1, "SharedUnityMenuModel");
5258
5359 qmlRegisterSingletonType<UnityMenuModelCache>(uri, 0, 1, "UnityMenuModelCache", menuModelCacheSingleton);
5460
plugins/Unity/Indicators/plugin.h+1−1
@@ -22,7 +22,7 @@
2222
2323#include <QtQml/QQmlExtensionPlugin>
2424
25−class Indicators2Plugin : public QQmlExtensionPlugin
25+class IndicatorsPlugin : public QQmlExtensionPlugin
2626{
2727 Q_OBJECT
2828 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
plugins/Unity/Indicators/sharedunitymenumodel.cppnew file+87
@@ -0,0 +1,87 @@
1+/*
2+ * Copyright 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 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+ */
17+
18+#include "sharedunitymenumodel.h"
19+#include "unitymenumodelcache.h"
20+
21+SharedUnityMenuModel::SharedUnityMenuModel(QObject* parent)
22+ : QObject(parent)
23+{
24+}
25+
26+QByteArray SharedUnityMenuModel::busName() const
27+{
28+ return m_busName;
29+}
30+
31+void SharedUnityMenuModel::setBusName(const QByteArray& busName)
32+{
33+ if (m_busName != busName) {
34+ m_busName = busName;
35+ Q_EMIT busNameChanged();
36+ initialize();
37+ }
38+}
39+
40+QByteArray SharedUnityMenuModel::menuObjectPath() const
41+{
42+ return m_menuObjectPath;
43+}
44+
45+void SharedUnityMenuModel::setMenuObjectPath(const QByteArray& menuObjectPath)
46+{
47+ if (m_menuObjectPath != menuObjectPath) {
48+ m_menuObjectPath = menuObjectPath;
49+ Q_EMIT menuObjectPathChanged();
50+ initialize();
51+ }
52+}
53+
54+QVariantMap SharedUnityMenuModel::actions() const
55+{
56+ return m_actions;
57+}
58+
59+void SharedUnityMenuModel::setActions(const QVariantMap& actions)
60+{
61+ if (m_actions != actions) {
62+ m_actions = actions;
63+ Q_EMIT actionsChanged();
64+ initialize();
65+ }
66+}
67+
68+UnityMenuModel* SharedUnityMenuModel::model() const
69+{
70+ return m_model ? m_model.data() : nullptr;
71+}
72+
73+void SharedUnityMenuModel::initialize()
74+{
75+ if (m_busName.isEmpty() || m_menuObjectPath.isEmpty() || m_actions.isEmpty()) {
76+ if (!m_model.isNull()) {
77+ m_model.clear();
78+ Q_EMIT modelChanged();
79+ }
80+ } else {
81+ QSharedPointer<UnityMenuModel> model = UnityMenuModelCache::singleton()->model(m_busName, m_menuObjectPath, m_actions);
82+ if (model != m_model) {
83+ m_model = model;
84+ Q_EMIT modelChanged();
85+ }
86+ }
87+}
plugins/Unity/Indicators/sharedunitymenumodel.hnew file+66
@@ -0,0 +1,66 @@
1+/*
2+ * Copyright 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 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+ */
17+
18+#ifndef SHAREDUNITYMENUMODEL_H
19+#define SHAREDUNITYMENUMODEL_H
20+
21+#include "unityindicatorsglobal.h"
22+
23+#include <QObject>
24+#include <QSharedPointer>
25+#include <QVariantMap>
26+
27+class UnityMenuModel;
28+
29+class UNITYINDICATORS_EXPORT SharedUnityMenuModel : public QObject
30+{
31+ Q_OBJECT
32+ Q_PROPERTY(QByteArray busName READ busName WRITE setBusName NOTIFY busNameChanged)
33+ Q_PROPERTY(QByteArray menuObjectPath READ menuObjectPath WRITE setMenuObjectPath NOTIFY menuObjectPathChanged)
34+ Q_PROPERTY(QVariantMap actions READ actions WRITE setActions NOTIFY actionsChanged)
35+ Q_PROPERTY(UnityMenuModel* model READ model NOTIFY modelChanged)
36+
37+public:
38+ SharedUnityMenuModel(QObject* parent = nullptr);
39+
40+ QByteArray busName() const;
41+ void setBusName(const QByteArray&);
42+
43+ QByteArray menuObjectPath() const;
44+ void setMenuObjectPath(const QByteArray&);
45+
46+ QVariantMap actions() const;
47+ void setActions(const QVariantMap&);
48+
49+ UnityMenuModel* model() const;
50+
51+Q_SIGNALS:
52+ void busNameChanged();
53+ void menuObjectPathChanged();
54+ void actionsChanged();
55+ void modelChanged();
56+
57+private:
58+ void initialize();
59+
60+ QByteArray m_busName;
61+ QByteArray m_menuObjectPath;
62+ QVariantMap m_actions;
63+ QSharedPointer<UnityMenuModel> m_model;
64+};
65+
66+#endif // SHAREDUNITYMENUMODEL_H
plugins/Unity/Indicators/unitymenumodelcache.cpp+27−12
@@ -20,30 +20,45 @@
2020#include "unitymenumodelcache.h"
2121#include <unitymenumodel.h>
2222
23−UnityMenuModelCache::UnityMenuModelCache(QObject* parent)
24− : QObject(parent)
23+#include <QQmlEngine>
24+
25+QPointer<UnityMenuModelCache> UnityMenuModelCache::theCache = nullptr;
26+
27+UnityMenuModelCache* UnityMenuModelCache::singleton()
2528{
29+ if (theCache.isNull()) {
30+ theCache = new UnityMenuModelCache();
31+ }
32+ return theCache.data();
2633}
2734
28−UnityMenuModelCache::~UnityMenuModelCache()
35+UnityMenuModelCache::UnityMenuModelCache(QObject* parent)
36+ : QObject(parent)
2937{
3038}
3139
32−UnityMenuModel* UnityMenuModelCache::model(const QByteArray& bus,
33− const QByteArray& path,
34− const QVariantMap& actions)
40+QSharedPointer<UnityMenuModel> UnityMenuModelCache::model(const QByteArray& bus,
41+ const QByteArray& path,
42+ const QVariantMap& actions)
3543{
3644 if (m_registry.contains(path))
3745 return m_registry[path];
3846
39− UnityMenuModel* menuModel = new UnityMenuModel;
40− connect(menuModel, &QObject::destroyed, this, [menuModel, this](QObject*) {
41− QList<QByteArray> keys = m_registry.keys(menuModel);
42− Q_FOREACH(const QByteArray& key, keys) {
43− m_registry.remove(key);
47+ UnityMenuModel* model = new UnityMenuModel;
48+ QQmlEngine::setObjectOwnership(model, QQmlEngine::CppOwnership);
49+
50+ QSharedPointer<UnityMenuModel> menuModel(model);
51+ connect(model, &QObject::destroyed, this, [this] {
52+ QMutableHashIterator<QByteArray, QWeakPointer<UnityMenuModel>> iter(m_registry);
53+ while(iter.hasNext()) {
54+ auto keyVal = iter.next();
55+ if (keyVal.value().isNull()) {
56+ iter.remove();
57+ break;
58+ }
4459 }
4560 });
46− m_registry[path] = menuModel;
61+ m_registry[path] = menuModel.toWeakRef();
4762
4863 menuModel->setBusName(bus);
4964 menuModel->setMenuObjectPath(path);
plugins/Unity/Indicators/unitymenumodelcache.h+13−7
@@ -24,6 +24,8 @@
2424
2525#include <QObject>
2626#include <QHash>
27+#include <QPointer>
28+#include <QWeakPointer>
2729
2830class UnityMenuModel;
2931
@@ -32,15 +34,19 @@ class UNITYINDICATORS_EXPORT UnityMenuModelCache : public QObject
3234 Q_OBJECT
3335public:
3436 UnityMenuModelCache(QObject*parent=nullptr);
35− ~UnityMenuModelCache();
3637
37− Q_INVOKABLE UnityMenuModel* model(const QByteArray& bus,
38− const QByteArray& path,
39− const QVariantMap& actions);
40− Q_INVOKABLE bool contains(const QByteArray& path);
38+ static UnityMenuModelCache* singleton();
4139
42−private:
43− QHash<QByteArray, UnityMenuModel*> m_registry;
40+ virtual QSharedPointer<UnityMenuModel> model(const QByteArray& bus,
41+ const QByteArray& path,
42+ const QVariantMap& actions);
43+
44+ // for tests use
45+ Q_INVOKABLE virtual bool contains(const QByteArray& path);
46+
47+protected:
48+ QHash<QByteArray, QWeakPointer<UnityMenuModel>> m_registry;
49+ static QPointer<UnityMenuModelCache> theCache;
4450};
4551
4652#endif // UNITYMENUMODELCACHE_H
plugins/Unity/Launcher/Launcher.qmltypes+17−12
@@ -13,14 +13,6 @@ Module {
1313 exports: ["Unity.Launcher/LauncherItem 0.1"]
1414 isCreatable: false
1515 exportMetaObjectRevisions: [0]
16− Signal {
17− name: "favoriteChanged"
18− Parameter { name: "favorite"; type: "bool" }
19− }
20− Signal {
21− name: "runningChanged"
22− Parameter { name: "running"; type: "bool" }
23− }
2416 }
2517 Component {
2618 name: "LauncherModel"
@@ -29,6 +21,10 @@ Module {
2921 isCreatable: false
3022 isSingleton: true
3123 exportMetaObjectRevisions: [0]
24+ Method {
25+ name: "requestRemove"
26+ Parameter { name: "appId"; type: "string" }
27+ }
3228 Method {
3329 name: "get"
3430 type: "unity::shell::launcher::LauncherItemInterface*"
@@ -48,10 +44,6 @@ Module {
4844 name: "pin"
4945 Parameter { name: "appId"; type: "string" }
5046 }
51− Method {
52− name: "requestRemove"
53− Parameter { name: "appId"; type: "string" }
54− }
5547 Method {
5648 name: "quickListActionInvoked"
5749 Parameter { name: "appId"; type: "string" }
@@ -88,6 +80,7 @@ Module {
8880 Property { name: "recent"; type: "bool"; isReadonly: true }
8981 Property { name: "progress"; type: "int"; isReadonly: true }
9082 Property { name: "count"; type: "int"; isReadonly: true }
83+ Property { name: "countVisible"; type: "bool"; isReadonly: true }
9184 Property { name: "focused"; type: "bool"; isReadonly: true }
9285 Property {
9386 name: "quickList"
@@ -95,6 +88,14 @@ Module {
9588 isReadonly: true
9689 isPointer: true
9790 }
91+ Signal {
92+ name: "nameChanged"
93+ Parameter { name: "name"; type: "string" }
94+ }
95+ Signal {
96+ name: "iconChanged"
97+ Parameter { name: "icon"; type: "string" }
98+ }
9899 Signal {
99100 name: "pinnedChanged"
100101 Parameter { name: "pinned"; type: "bool" }
@@ -115,6 +116,10 @@ Module {
115116 name: "countChanged"
116117 Parameter { name: "count"; type: "int" }
117118 }
119+ Signal {
120+ name: "countVisibleChanged"
121+ Parameter { name: "countVisible"; type: "bool" }
122+ }
118123 Signal {
119124 name: "focusedChanged"
120125 Parameter { name: "focused"; type: "bool" }
plugins/Unity/Session/Session.qmltypes+10
@@ -34,4 +34,14 @@ Module {
3434 Method { name: "RequestReboot" }
3535 Method { name: "RequestShutdown" }
3636 }
37+ Component {
38+ name: "OrientationLock"
39+ prototype: "QObject"
40+ exports: ["Unity.Session/OrientationLock 0.1"]
41+ isCreatable: false
42+ isSingleton: true
43+ exportMetaObjectRevisions: [0]
44+ Property { name: "enabled"; type: "bool"; isReadonly: true }
45+ Property { name: "savedOrientation"; type: "Qt::ScreenOrientation" }
46+ }
3747}
plugins/Utils/Utils.qmltypes+6
@@ -106,6 +106,12 @@ Module {
106106 Parameter { name: "row"; type: "int" }
107107 }
108108 }
109+ Component {
110+ name: "RelativeTimeFormatter"
111+ prototype: "TimeFormatter"
112+ exports: ["Utils/RelativeTimeFormatter 0.1"]
113+ exportMetaObjectRevisions: [0]
114+ }
109115 Component {
110116 name: "TimeFormatter"
111117 prototype: "QObject"
qml/Greeter/Clock.qml+9−9
@@ -34,21 +34,21 @@ Item {
3434 }
3535 }
3636
37− CachedUnityMenuModel {
37+ Indicators.SharedUnityMenuModel {
3838 id: timeModel
3939 objectName: "timeModel"
4040
4141 busName: "com.canonical.indicator.datetime"
42− actionsObjectPath: "/com/canonical/indicator/datetime"
42+ actions: { "indicator": "/com/canonical/indicator/datetime" }
4343 menuObjectPath: clock.visible ? "/com/canonical/indicator/datetime/phone" : ""
44+ }
4445
45− Indicators.RootActionState {
46− menu: timeModel.model
47− onUpdated: {
48− if (timeLabel.text != rightLabel) {
49− timeLabel.text = rightLabel;
50− clock.currentDate = new Date();
51− }
46+ Indicators.RootActionState {
47+ menu: timeModel.model
48+ onUpdated: {
49+ if (timeLabel.text != rightLabel) {
50+ if (rightLabel != "") timeLabel.text = rightLabel;
51+ clock.currentDate = new Date();
5252 }
5353 }
5454 }
qml/Panel/Indicators/CachedUnityMenuModel.qmldeleted−39
@@ -1,39 +0,0 @@
1−/*
2− * Copyright 2013 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU 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− * Nick Dedekind <nick.dedekind@canonical.com>
18− */
19−
20−import QtQuick 2.0
21−import QMenuModel 0.1
22−import Unity.Indicators 0.1 as Indicators
23−
24−// Make sure we don't duplicate models.
25−Item {
26− id: cachedModel
27− property string busName
28− property string actionsObjectPath
29− property string menuObjectPath
30− readonly property bool ready: busName!=="" && actionsObjectPath!=="" && menuObjectPath!==""
31−
32− property var model: {
33− if (!ready) return null;
34−
35− return Indicators.UnityMenuModelCache.model(cachedModel.busName,
36− cachedModel.menuObjectPath,
37− { "indicator": cachedModel.actionsObjectPath });
38− }
39−}
qml/Panel/Indicators/IndicatorBase.qml+2−2
@@ -37,10 +37,10 @@ Item {
3737 property alias menuModel: cachedModel.model
3838 property alias rootActionState: rootAction
3939
40− CachedUnityMenuModel {
40+ SharedUnityMenuModel {
4141 id: cachedModel
4242 busName: indicatorItem.busName
43− actionsObjectPath: indicatorItem.actionsObjectPath
43+ actions: { "indicator": indicatorItem.actionsObjectPath }
4444 menuObjectPath: indicatorItem.deviceMenuObjectPath
4545 }
4646
tests/mocks/AccountsService/AccountsService.qmltypes+2
@@ -23,6 +23,8 @@ Module {
2323 }
2424 Property { name: "user"; type: "string" }
2525 Property { name: "demoEdges"; type: "bool" }
26+ Property { name: "enableLauncherWhileLocked"; type: "bool" }
27+ Property { name: "enableIndicatorsWhileLocked"; type: "bool" }
2628 Property { name: "backgroundFile"; type: "string" }
2729 Property { name: "statsWelcomeScreen"; type: "bool" }
2830 Property { name: "passwordDisplayHint"; type: "PasswordDisplayHint"; isReadonly: true }
tests/mocks/LightDM/LightDM.qmltypes+1
@@ -37,6 +37,7 @@ Module {
3737 Signal { name: "isActiveChanged" }
3838 Signal { name: "isAuthenticatedChanged" }
3939 Signal { name: "showGreeter" }
40+ Signal { name: "hideGreeter" }
4041 Signal {
4142 name: "requestAuthenticationUser"
4243 Parameter { name: "user"; type: "string" }
tests/mocks/QMenuModel/QMenuModel.qmltypes+1−1
@@ -18,12 +18,12 @@ Module {
1818 prototype: "QAbstractListModel"
1919 exports: ["QMenuModel/UnityMenuModel 0.1"]
2020 exportMetaObjectRevisions: [0]
21− Property { name: "modelData"; type: "QVariant" }
2221 Property { name: "busName"; type: "QByteArray" }
2322 Property { name: "actions"; type: "QVariantMap" }
2423 Property { name: "menuObjectPath"; type: "QByteArray" }
2524 Property { name: "actionStateParser"; type: "ActionStateParser"; isPointer: true }
2625 Property { name: "nameOwner"; type: "string"; isReadonly: true }
26+ Property { name: "modelData"; type: "QVariant" }
2727 Method {
2828 name: "insertRow"
2929 Parameter { name: "row"; type: "int" }
tests/mocks/QMenuModel/unitymenumodel.cpp+1−2
@@ -50,13 +50,12 @@ void UnityMenuModel::setModelData(const QVariant& data)
5050{
5151 beginResetModel();
5252
53− m_modelData.clear();
5453 m_modelData = data.toList();
54+ Q_EMIT modelDataChanged();
5555
5656 endResetModel();
5757}
5858
59−
6059void UnityMenuModel::insertRow(int row, const QVariant& data)
6160{
6261 row = qMin(row, rowCount());
tests/mocks/QMenuModel/unitymenumodel.h+6−2
@@ -27,13 +27,15 @@ class ActionStateParser;
2727class Q_DECL_EXPORT UnityMenuModel : public QAbstractListModel
2828{
2929 Q_OBJECT
30− Q_PROPERTY(QVariant modelData READ modelData WRITE setModelData NOTIFY modelDataChanged)
3130 Q_PROPERTY(QByteArray busName READ busName WRITE setBusName NOTIFY busNameChanged)
3231 Q_PROPERTY(QVariantMap actions READ actions WRITE setActions NOTIFY actionsChanged)
3332 Q_PROPERTY(QByteArray menuObjectPath READ menuObjectPath WRITE setMenuObjectPath NOTIFY menuObjectPathChanged)
3433 Q_PROPERTY(ActionStateParser* actionStateParser READ actionStateParser WRITE setActionStateParser NOTIFY actionStateParserChanged)
3534 Q_PROPERTY(QString nameOwner READ nameOwner NOTIFY nameOwnerChanged)
3635
36+ // internal mock properties
37+ Q_PROPERTY(QVariant modelData READ modelData WRITE setModelData NOTIFY modelDataChanged)
38+
3739public:
3840 UnityMenuModel(QObject *parent = nullptr);
3941 virtual ~UnityMenuModel();
@@ -81,9 +83,11 @@ Q_SIGNALS:
8183 void actionsChanged();
8284 void menuObjectPathChanged();
8385 void actionStateParserChanged();
84− void modelDataChanged();
8586 void nameOwnerChanged();
8687
88+ // Internal mock usage
89+ void modelDataChanged();
90+
8791private:
8892 QVariantMap rowData(int row) const;
8993 QVariant subMenuData(int row) const;
tests/mocks/Ubuntu/Payments/Payments.qmltypes+2
@@ -37,6 +37,8 @@ Module {
3737 Parameter { name: "error"; type: "string" }
3838 }
3939 Signal { name: "purchaseCompleted" }
40+ Signal { name: "purchaseCancelled" }
4041 Method { name: "start" }
42+ Method { name: "process" }
4143 }
4244}
tests/mocks/Ubuntu/Telephony/Telephony.qmltypes+2−1
@@ -22,7 +22,8 @@ Module {
2222 exportMetaObjectRevisions: [0]
2323 Property { name: "phoneNumber"; type: "string" }
2424 Property { name: "isConference"; type: "bool" }
25− Property { name: "elapsedTime"; type: "int"; isReadonly: true }
25+ Property { name: "elapsedTime"; type: "int" }
26+ Property { name: "elapsedTimerRunning"; type: "bool" }
2627 }
2728 Component {
2829 name: "MockCallManager"
tests/mocks/Unity/Application/Application.qmltypes+13
@@ -238,6 +238,7 @@ Module {
238238 Property { name: "state"; type: "State"; isReadonly: true }
239239 Property { name: "name"; type: "string"; isReadonly: true }
240240 Property { name: "live"; type: "bool"; isReadonly: true }
241+ Property { name: "orientation"; type: "Qt::ScreenOrientation" }
241242 Signal {
242243 name: "typeChanged"
243244 Parameter { type: "Type" }
@@ -268,9 +269,14 @@ Module {
268269 exportMetaObjectRevisions: [0]
269270 Property { name: "name"; type: "string"; isReadonly: true }
270271 Property { name: "surface"; type: "MirSurfaceItem"; isReadonly: true; isPointer: true }
272+ Property { name: "application"; type: "ApplicationInfo"; isReadonly: true; isPointer: true }
271273 Property { name: "parentSession"; type: "Session"; isReadonly: true; isPointer: true }
272274 Property { name: "childSessions"; type: "SessionModel"; isReadonly: true; isPointer: true }
273275 Property { name: "live"; type: "bool"; isReadonly: true }
276+ Signal {
277+ name: "applicationChanged"
278+ Parameter { type: "ApplicationInfo"; isPointer: true }
279+ }
274280 Signal {
275281 name: "surfaceChanged"
276282 Parameter { type: "MirSurfaceItem"; isPointer: true }
@@ -368,6 +374,12 @@ Module {
368374 Property { name: "stage"; type: "Stage"; isReadonly: true }
369375 Property { name: "state"; type: "State"; isReadonly: true }
370376 Property { name: "focused"; type: "bool"; isReadonly: true }
377+ Property { name: "splashTitle"; type: "string"; isReadonly: true }
378+ Property { name: "splashImage"; type: "QUrl"; isReadonly: true }
379+ Property { name: "splashShowHeader"; type: "bool"; isReadonly: true }
380+ Property { name: "splashColor"; type: "QColor"; isReadonly: true }
381+ Property { name: "splashColorHeader"; type: "QColor"; isReadonly: true }
382+ Property { name: "splashColorFooter"; type: "QColor"; isReadonly: true }
371383 Signal {
372384 name: "nameChanged"
373385 Parameter { name: "name"; type: "string" }
@@ -414,6 +426,7 @@ Module {
414426 Property { name: "count"; type: "int"; isReadonly: true }
415427 Property { name: "focusedApplicationId"; type: "string"; isReadonly: true }
416428 Property { name: "suspended"; type: "bool" }
429+ Property { name: "forceDashActive"; type: "bool" }
417430 Signal {
418431 name: "focusRequested"
419432 Parameter { name: "appId"; type: "string" }
tests/mocks/Unity/DashCommunicator/DashCommunicator.qmltypes+2−2
@@ -34,13 +34,13 @@ Module {
3434 name: "setCurrentScopeRequested"
3535 Parameter { name: "scopeId"; type: "string" }
3636 Parameter { name: "animate"; type: "bool" }
37− Parameter { name: "reset"; type: "bool" }
37+ Parameter { name: "isSwipe"; type: "bool" }
3838 }
3939 Method {
4040 name: "mockSetCurrentScope"
4141 Parameter { name: "scopeId"; type: "string" }
4242 Parameter { name: "animate"; type: "bool" }
43− Parameter { name: "reset"; type: "bool" }
43+ Parameter { name: "isSwipe"; type: "bool" }
4444 }
4545 }
4646}
tests/mocks/Unity/Indicators/CMakeLists.txt+3−10
@@ -12,24 +12,17 @@ include_directories(
1212
1313set(IndicatorsFakeQml_SOURCES
1414 fakeplugin.cpp
15+ fakeindicatorsmodel.cpp
16+ fakeunitymenumodelcache.cpp
1517 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/indicators.h
1618 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/menucontentactivator.cpp
19+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/sharedunitymenumodel.cpp
1720 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/unitymenumodelcache.cpp
1821 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/unitymenumodelstack.cpp
1922 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/visibleindicatorsmodel.cpp
20− fakeindicatorsmodel.cpp
21−)
22−
23−set(IndicatorsFakeQml_RESOURCES
24− indicators_fake.qrc
25−)
26−
27−qt5_add_resources(IndicatorsFakeQml_RESOURCES_RCC
28− ${IndicatorsFakeQml_RESOURCES}
2923)
3024
3125add_library(IndicatorsFakeQml SHARED
32− ${IndicatorsFakeQml_RESOURCES_RCC}
3326 ${IndicatorsFakeQml_SOURCES}
3427)
3528add_definitions(-DUNITYINDICATORS_LIBRARY)
tests/mocks/Unity/Indicators/FakeMenuPage.qmldeleted−27
@@ -1,27 +0,0 @@
1−/*
2− * Copyright 2013 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−
19−Flickable {
20− objectName: "fakeMenuPlugin"
21− // Make it compatible with the PluginItem interface
22− function reset() {
23− if (shell != undefined && shell.indicator_status != undefined) {
24− shell.indicator_status[objectName].reset++;
25− }
26− }
27−}
tests/mocks/Unity/Indicators/Indicators.qmltypes+41−11
@@ -29,6 +29,7 @@ Module {
2929 exports: ["Unity.Indicators/FakeIndicatorsModel 0.1"]
3030 exportMetaObjectRevisions: [0]
3131 Property { name: "count"; type: "int"; isReadonly: true }
32+ Property { name: "modelData"; type: "QVariant" }
3233 Method {
3334 name: "load"
3435 Parameter { name: "profile"; type: "string" }
@@ -38,6 +39,15 @@ Module {
3839 name: "append"
3940 Parameter { name: "row"; type: "QVariantMap" }
4041 }
42+ Method {
43+ name: "insert"
44+ Parameter { name: "row"; type: "int" }
45+ Parameter { name: "data"; type: "QVariantMap" }
46+ }
47+ Method {
48+ name: "remove"
49+ Parameter { name: "row"; type: "int" }
50+ }
4151 Method {
4252 name: "data"
4353 type: "QVariant"
@@ -45,6 +55,27 @@ Module {
4555 Parameter { name: "role"; type: "int" }
4656 }
4757 }
58+ Component {
59+ name: "FakeUnityMenuModelCache"
60+ prototype: "UnityMenuModelCache"
61+ exports: ["Unity.Indicators/UnityMenuModelCache 0.1"]
62+ isCreatable: false
63+ isSingleton: true
64+ exportMetaObjectRevisions: [0]
65+ Method {
66+ name: "setCachedModelData"
67+ Parameter { name: "bus"; type: "QByteArray" }
68+ Parameter { name: "path"; type: "QByteArray" }
69+ Parameter { name: "actions"; type: "QVariantMap" }
70+ Parameter { name: "data"; type: "QVariant" }
71+ }
72+ Method {
73+ name: "setCachedModelData"
74+ Parameter { name: "bus"; type: "QByteArray" }
75+ Parameter { name: "path"; type: "QByteArray" }
76+ Parameter { name: "actions"; type: "QVariantMap" }
77+ }
78+ }
4879 Component {
4980 name: "FlatMenuProxyModelRole"
5081 prototype: "QObject"
@@ -160,19 +191,18 @@ Module {
160191 }
161192 Component { name: "QIdentityProxyModel"; prototype: "QAbstractProxyModel" }
162193 Component {
163− name: "UnityMenuModelCache"
194+ name: "SharedUnityMenuModel"
164195 prototype: "QObject"
165− exports: ["Unity.Indicators/UnityMenuModelCache 0.1"]
166− isCreatable: false
167− isSingleton: true
196+ exports: ["Unity.Indicators/SharedUnityMenuModel 0.1"]
168197 exportMetaObjectRevisions: [0]
169− Method {
170− name: "model"
171− type: "UnityMenuModel*"
172− Parameter { name: "bus"; type: "QByteArray" }
173− Parameter { name: "path"; type: "QByteArray" }
174− Parameter { name: "actions"; type: "QVariantMap" }
175− }
198+ Property { name: "busName"; type: "QByteArray" }
199+ Property { name: "menuObjectPath"; type: "QByteArray" }
200+ Property { name: "actions"; type: "QVariantMap" }
201+ Property { name: "model"; type: "UnityMenuModel"; isReadonly: true; isPointer: true }
202+ }
203+ Component {
204+ name: "UnityMenuModelCache"
205+ prototype: "QObject"
176206 Method {
177207 name: "contains"
178208 type: "bool"
tests/mocks/Unity/Indicators/IndicatorsModel.qml+143−35
@@ -18,43 +18,151 @@ import QtQuick 2.0
1818import Unity.Indicators 0.1 as Indicators
1919
2020Indicators.FakeIndicatorsModel {
21+ id: root
22+
23+ Component.onCompleted: {
24+ Indicators.UnityMenuModelCache.setCachedModelData("com.canonical.indicators.fake1",
25+ "/com/canonical/indicators/fake1",
26+ "/com/canonical/indicators/fake1",
27+ getUnityMenuModelData("fake-indicator-bluetooth",
28+ "Bluetooth (F)",
29+ "",
30+ [ "image://theme/bluetooth-active" ]));
31+ Indicators.UnityMenuModelCache.setCachedModelData("com.canonical.indicators.fake2",
32+ "/com/canonical/indicators/fake2",
33+ "/com/canonical/indicators/fake2",
34+ getUnityMenuModelData("fake-indicator-network",
35+ "Network (F)",
36+ "",
37+ [ "image://theme/simcard-error", "image://theme/wifi-high" ]));
38+ Indicators.UnityMenuModelCache.setCachedModelData("com.canonical.indicators.fake3",
39+ "/com/canonical/indicators/fake3",
40+ "/com/canonical/indicators/fake3",
41+ getUnityMenuModelData("fake-indicator-sound",
42+ "Messages (F)",
43+ "",
44+ [ "image://theme/messages-new" ]));
45+ Indicators.UnityMenuModelCache.setCachedModelData("com.canonical.indicators.fake4",
46+ "/com/canonical/indicators/fake4",
47+ "/com/canonical/indicators/fake4",
48+ getUnityMenuModelData("fake-indicator-power",
49+ "Sound (F)",
50+ "",
51+ [ "image://theme/audio-volume-high" ]));
52+ Indicators.UnityMenuModelCache.setCachedModelData("com.canonical.indicators.fake5",
53+ "/com/canonical/indicators/fake5",
54+ "/com/canonical/indicators/fake5",
55+ getUnityMenuModelData("fake-indicator-power",
56+ "Battery (F)",
57+ "",
58+ [ "image://theme/battery-020" ]));
59+ }
60+
61+ function getUnityMenuModelData(identifier, title, label, icons) {
62+ var root = [{
63+ "rowData": { // 1
64+ "label": "",
65+ "sensitive": true,
66+ "isSeparator": false,
67+ "icon": "",
68+ "type": "com.canonical.indicator.root",
69+ "ext": {},
70+ "action": "",
71+ "actionState": {
72+ "title": title,
73+ "label": label,
74+ "icons": icons
75+ },
76+ "isCheck": false,
77+ "isRadio": false,
78+ "isToggled": false,
79+ },
80+ "submenu": []
81+ }];
82+
83+ var submenus = [];
84+ for (var i = 0; i < 8; i++) {
85+ var submenu = {
86+ "rowData": { // 1.1
87+ "label": identifier,
88+ "sensitive": true,
89+ "isSeparator": false,
90+ "icon": "",
91+ "type": undefined,
92+ "ext": {},
93+ "action": "",
94+ "actionState": {},
95+ "isCheck": false,
96+ "isRadio": false,
97+ "isToggled": false,
98+ }};
99+ submenus.push(submenu);
100+ }
101+ root[0]["submenu"] = submenus;
102+
103+ return root;
104+ }
105+
106+ property var originalModelData: [
107+ {
108+ "identifier": "indicator-fake1",
109+ "widgetSource": "Indicators/DefaultIndicatorWidget.qml",
110+ "pageSource": "Indicators/DefaultIndicatorPage.qml",
111+ "indicatorProperties": {
112+ "enabled": true,
113+ "busName": "com.canonical.indicators.fake1",
114+ "menuObjectPath": "/com/canonical/indicators/fake1",
115+ "actionsObjectPath": "/com/canonical/indicators/fake1"
116+ }
117+ },
118+ {
119+ "identifier": "indicator-fake2",
120+ "widgetSource": "Indicators/DefaultIndicatorWidget.qml",
121+ "pageSource": "Indicators/DefaultIndicatorPage.qml",
122+ "indicatorProperties": {
123+ "enabled": true,
124+ "busName": "com.canonical.indicators.fake2",
125+ "menuObjectPath": "/com/canonical/indicators/fake2",
126+ "actionsObjectPath": "/com/canonical/indicators/fake2"
127+ }
128+ },
129+ {
130+ "identifier": "indicator-fake3",
131+ "widgetSource": "Indicators/DefaultIndicatorWidget.qml",
132+ "pageSource": "Indicators/DefaultIndicatorPage.qml",
133+ "indicatorProperties": {
134+ "enabled": true,
135+ "busName": "com.canonical.indicators.fake3",
136+ "menuObjectPath": "/com/canonical/indicators/fake3",
137+ "actionsObjectPath": "/com/canonical/indicators/fake3"
138+ }
139+ },
140+ {
141+ "identifier": "indicator-fake4",
142+ "widgetSource": "Indicators/DefaultIndicatorWidget.qml",
143+ "pageSource": "Indicators/DefaultIndicatorPage.qml",
144+ "indicatorProperties": {
145+ "enabled": true,
146+ "busName": "com.canonical.indicators.fake4",
147+ "menuObjectPath": "/com/canonical/indicators/fake4",
148+ "actionsObjectPath": "/com/canonical/indicators/fake4"
149+ }
150+ },
151+ {
152+ "identifier": "indicator-fake5",
153+ "widgetSource": "Indicators/DefaultIndicatorWidget.qml",
154+ "pageSource": "Indicators/DefaultIndicatorPage.qml",
155+ "indicatorProperties": {
156+ "enabled": true,
157+ "busName": "com.canonical.indicators.fake5",
158+ "menuObjectPath": "/com/canonical/indicators/fake5",
159+ "actionsObjectPath": "/com/canonical/indicators/fake5"
160+ }
161+ }
162+ ]
21163
22164 function load(profile) {
23165 unload();
24−
25− append({ "identifier": "indicator-fake1",
26− "position": 0,
27− "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget1.qml",
28− "pageSource": "qrc:/tests/indciators/qml/fake_menu_page1.qml",
29− "indicatorProperties": { enabled: true }
30− });
31−
32− append({ "identifier": "indicator-fake2",
33− "position": 1,
34− "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget2.qml",
35− "pageSource": "qrc:/tests/indciators/qml/fake_menu_page2.qml",
36− "indicatorProperties": { enabled: true }
37− });
38−
39− append({ "identifier": "indicator-fake3",
40− "position": 2,
41− "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget3.qml",
42− "pageSource": "qrc:/tests/indciators/qml/fake_menu_page3.qml",
43− "indicatorProperties": { enabled: true }
44− });
45−
46− append({ "identifier": "indicator-fake4",
47− "position": 3,
48− "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget4.qml",
49− "pageSource": "qrc:/tests/indciators/qml/fake_menu_page4.qml",
50− "indicatorProperties": { enabled: true }
51− });
52−
53− append({ "identifier": "indicator-fake5",
54− "position": 4,
55− "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget5.qml",
56− "pageSource": "qrc:/tests/indciators/qml/fake_menu_page5.qml",
57− "indicatorProperties": { enabled: true }
58− });
166+ root.modelData = originalModelData;
59167 }
60168}
tests/mocks/Unity/Indicators/RootActionState.qml+17−9
@@ -19,15 +19,23 @@
1919
2020import QtQuick 2.0
2121
22−QtObject {
23− property var menu
24− property bool valid: false
25− property string title
26− property string leftLabel
27− property string rightLabel
28− property var icons
29− property string accessibleName
30− property bool visible: true
22+Item {
23+ property var menu: null
24+ property bool valid: cachedState !== undefined
25+ property string title: cachedState && cachedState.hasOwnProperty("title") ? cachedState["title"] : ""
26+ property string leftLabel: cachedState && cachedState.hasOwnProperty("pre-label") ? cachedState["pre-label"] : ""
27+ property string rightLabel: cachedState && cachedState.hasOwnProperty("label") ? cachedState["label"] : ""
28+ property var icons: cachedState && cachedState.hasOwnProperty("icons") ? cachedState["icons"] : []
29+ property string accessibleName: cachedState && cachedState.hasOwnProperty("accessible-desc") ? cachedState["accessible-desc"] : ""
30+ visible: cachedState && cachedState.hasOwnProperty("visible") ? cachedState["visible"] : true
31+
32+ property var cachedState: menu ? menu.get(0, "actionState") : undefined
33+ Connections {
34+ target: menu
35+ onModelDataChanged: {
36+ cachedState = menu.get(0, "actionState");
37+ }
38+ }
3139
3240 signal updated
3341
tests/mocks/Unity/Indicators/fakeindicatorsmodel.cpp+50−19
@@ -31,7 +31,6 @@ FakeIndicatorsModel::FakeIndicatorsModel(QObject *parent)
3131/*! \internal */
3232FakeIndicatorsModel::~FakeIndicatorsModel()
3333{
34− qDeleteAll(m_indicators);
3534}
3635
3736int FakeIndicatorsModel::count() const
@@ -47,31 +46,63 @@ void FakeIndicatorsModel::unload()
4746{
4847 beginResetModel();
4948
50− qDeleteAll(m_indicators);
51− m_indicators.clear();
49+ m_modelData.clear();
50+ Q_EMIT modelDataChanged();
5251
5352 endResetModel();
5453}
5554
5655
57−void FakeIndicatorsModel::append(const QVariantMap& row)
56+void FakeIndicatorsModel::append(const QVariantMap& data)
5857{
59− Indicator* new_row = new QHash<int, QVariant>();
60− for (auto iter = row.begin(); iter != row.end(); ++iter )
61− {
62− int key = roleNames().key(iter.key().toUtf8(), -1);
63− if (key != -1) {
64− new_row->insert(key, iter.value());
65− }
66− }
58+ QList<QVariant> allData = m_modelData.toList();
59+ beginInsertRows(QModelIndex(), allData.count(), allData.count());
60+
61+ allData.append(data);
62+ m_modelData = allData;
63+ Q_EMIT modelDataChanged();
6764
68− beginInsertRows(QModelIndex(), m_indicators.count(), m_indicators.count());
65+ endInsertRows();
66+}
6967
70− m_indicators.append(new_row);
68+void FakeIndicatorsModel::insert(int row, const QVariantMap& data)
69+{
70+ QList<QVariant> allData = m_modelData.toList();
71+ row = qMax(0, qMin(row, allData.count()));
72+
73+ beginInsertRows(QModelIndex(), row, row);
74+
75+ allData.insert(row, data);
76+ m_modelData = allData;
77+ Q_EMIT modelDataChanged();
7178
7279 endInsertRows();
7380}
7481
82+void FakeIndicatorsModel::remove(int row)
83+{
84+ QList<QVariant> allData = m_modelData.toList();
85+ row = qMax(0, qMin(row, allData.count()));
86+
87+ beginRemoveRows(QModelIndex(), row, row);
88+
89+ allData.removeAt(row);
90+ m_modelData = allData;
91+ Q_EMIT modelDataChanged();
92+
93+ endRemoveRows();
94+}
95+
96+void FakeIndicatorsModel::setModelData(const QVariant& modelData)
97+{
98+ beginResetModel();
99+
100+ m_modelData = modelData;
101+ Q_EMIT modelDataChanged();
102+
103+ endResetModel();
104+}
105+
75106QHash<int, QByteArray> FakeIndicatorsModel::roleNames() const
76107{
77108 static QHash<int, QByteArray> roles;
@@ -91,18 +122,18 @@ int FakeIndicatorsModel::columnCount(const QModelIndex &) const
91122 return 1;
92123}
93124
94−Q_INVOKABLE QVariant FakeIndicatorsModel::data(int row, int role) const
125+QVariant FakeIndicatorsModel::data(int row, int role) const
95126{
96127 return data(index(row, 0), role);
97128}
98129
99130QVariant FakeIndicatorsModel::data(const QModelIndex &index, int role) const
100131{
101− if (!index.isValid() || index.row() >= m_indicators.size())
132+ QList<QVariant> dataList = m_modelData.toList();
133+ if (!index.isValid() || index.row() >= dataList.size())
102134 return QVariant();
103135
104− Indicator* indicator = m_indicators[index.row()];
105− return indicator->value(role, QVariant());
136+ return dataList[index.row()].toMap()[roleNames()[role]];
106137}
107138
108139QModelIndex FakeIndicatorsModel::parent(const QModelIndex&) const
@@ -112,5 +143,5 @@ QModelIndex FakeIndicatorsModel::parent(const QModelIndex&) const
112143
113144int FakeIndicatorsModel::rowCount(const QModelIndex&) const
114145{
115− return m_indicators.count();
146+ return m_modelData.toList().count();
116147}
tests/mocks/Unity/Indicators/fakeindicatorsmodel.h+8−2
@@ -27,6 +27,7 @@ class FakeIndicatorsModel : public QAbstractListModel
2727 Q_OBJECT
2828 Q_ENUMS(Roles)
2929 Q_PROPERTY(int count READ count NOTIFY countChanged)
30+ Q_PROPERTY(QVariant modelData READ modelData WRITE setModelData NOTIFY modelDataChanged)
3031public:
3132
3233 FakeIndicatorsModel(QObject *parent=0);
@@ -36,9 +37,14 @@ public:
3637 Q_INVOKABLE void unload();
3738
3839 Q_INVOKABLE void append(const QVariantMap& row);
40+ Q_INVOKABLE void insert(int row, const QVariantMap& data);
41+ Q_INVOKABLE void remove(int row);
3942
4043 Q_INVOKABLE QVariant data(int row, int role) const;
4144
45+ void setModelData(const QVariant& data);
46+ QVariant modelData() const { return m_modelData; }
47+
4248 /* QAbstractItemModel */
4349 QHash<int, QByteArray> roleNames() const;
4450 int columnCount(const QModelIndex &parent = QModelIndex()) const;
@@ -48,12 +54,12 @@ public:
4854
4955Q_SIGNALS:
5056 void countChanged();
57+ void modelDataChanged();
5158
5259private:
5360 int count() const;
5461
55− typedef QHash<int, QVariant> Indicator;
56− QList<Indicator*> m_indicators;
62+ QVariant m_modelData;
5763};
5864
5965#endif // FAKE_INDICATORSMODEL_H
tests/mocks/Unity/Indicators/fakeplugin.cpp+8−4
@@ -26,19 +26,22 @@
2626#include "fakeindicatorsmodel.h"
2727#include "indicators.h"
2828#include "menucontentactivator.h"
29−#include "unitymenumodelcache.h"
29+#include "sharedunitymenumodel.h"
30+#include "fakeunitymenumodelcache.h"
3031#include "unitymenumodelstack.h"
3132#include "visibleindicatorsmodel.h"
3233
34+#include <unitymenumodel.h>
35+
3336static QObject* menuModelCacheSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
3437 Q_UNUSED(engine);
3538 Q_UNUSED(scriptEngine);
36− return new UnityMenuModelCache;
39+ return FakeUnityMenuModelCache::singleton();
3740}
3841
3942void IndicatorsFakePlugin::registerTypes(const char * uri)
4043{
41− Q_INIT_RESOURCE(indicators_fake);
44+ qRegisterMetaType<UnityMenuModel*>("UnityMenuModel*");
4245
4346 // internal
4447 qmlRegisterType<FakeIndicatorsModel>(uri, 0, 1, "FakeIndicatorsModel");
@@ -47,8 +50,9 @@ void IndicatorsFakePlugin::registerTypes(const char * uri)
4750 qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
4851 qmlRegisterType<UnityMenuModelStack>(uri, 0, 1, "UnityMenuModelStack");
4952 qmlRegisterType<VisibleIndicatorsModel>(uri, 0, 1, "VisibleIndicatorsModel");
53+ qmlRegisterType<SharedUnityMenuModel>(uri, 0, 1, "SharedUnityMenuModel");
5054
51− qmlRegisterSingletonType<UnityMenuModelCache>(uri, 0, 1, "UnityMenuModelCache", menuModelCacheSingleton);
55+ qmlRegisterSingletonType<FakeUnityMenuModelCache>(uri, 0, 1, "UnityMenuModelCache", menuModelCacheSingleton);
5256
5357 // external uncreatables
5458 qmlRegisterUncreatableType<MenuContentState>(uri, 0, 1, "MenuContentState", "Can't create MenuContentState class");
tests/mocks/Unity/Indicators/fakeunitymenumodelcache.cppnew file+57
@@ -0,0 +1,57 @@
1+/*
2+ * Copyright 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 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+
17+#include "fakeunitymenumodelcache.h"
18+#include <unitymenumodel.h>
19+
20+QPointer<FakeUnityMenuModelCache> FakeUnityMenuModelCache::theFakeCache = nullptr;
21+
22+FakeUnityMenuModelCache* FakeUnityMenuModelCache::singleton()
23+{
24+ if (theFakeCache.isNull()) {
25+ theFakeCache = new FakeUnityMenuModelCache();
26+ }
27+ return theFakeCache.data();
28+}
29+
30+FakeUnityMenuModelCache::FakeUnityMenuModelCache(QObject* parent)
31+ : UnityMenuModelCache(parent)
32+{
33+}
34+
35+QSharedPointer<UnityMenuModel> FakeUnityMenuModelCache::model(const QByteArray& bus,
36+ const QByteArray& path,
37+ const QVariantMap& actions)
38+{
39+ return UnityMenuModelCache::singleton()->model(bus, path, actions);
40+}
41+
42+bool FakeUnityMenuModelCache::contains(const QByteArray& path)
43+{
44+ return UnityMenuModelCache::singleton()->contains(path);
45+}
46+
47+void FakeUnityMenuModelCache::setCachedModelData(const QByteArray& bus,
48+ const QByteArray& path,
49+ const QVariantMap& actions,
50+ const QVariant& data)
51+{
52+ // keep a ref forever!
53+ if (!m_models.contains(path)) {
54+ m_models[path] = model(bus, path, actions);
55+ }
56+ m_models[path]->setModelData(data);
57+}
tests/mocks/Unity/Indicators/fakeunitymenumodelcache.hnew file+49
@@ -0,0 +1,49 @@
1+/*
2+ * Copyright 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 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+
17+#ifndef FAKEUNITYMENUMODELCACHE_H
18+#define FAKEUNITYMENUMODELCACHE_H
19+
20+#include "unitymenumodelcache.h"
21+
22+#include <QVariantMap>
23+
24+class FakeUnityMenuModelCache : public UnityMenuModelCache
25+{
26+ Q_OBJECT
27+public:
28+ FakeUnityMenuModelCache(QObject* parent = nullptr);
29+
30+ static FakeUnityMenuModelCache* singleton();
31+
32+ QSharedPointer<UnityMenuModel> model(const QByteArray& bus,
33+ const QByteArray& path,
34+ const QVariantMap& actions) override;
35+ bool contains(const QByteArray& path) override;
36+
37+
38+
39+ Q_INVOKABLE void setCachedModelData(const QByteArray& bus,
40+ const QByteArray& path,
41+ const QVariantMap& actions,
42+ const QVariant& data = QVariant());
43+
44+private:
45+ static QPointer<FakeUnityMenuModelCache> theFakeCache;
46+ QHash<QByteArray, QSharedPointer<UnityMenuModel>> m_models;
47+};
48+
49+#endif // FAKEUNITYMENUMODELCACHE_H
tests/mocks/Unity/Indicators/indicators_fake.qrcdeleted−14
@@ -1,14 +0,0 @@
1−<RCC>
2− <qresource prefix="/tests/indciators">
3− <file>qml/fake_menu_widget1.qml</file>
4− <file>qml/fake_menu_widget2.qml</file>
5− <file>qml/fake_menu_widget3.qml</file>
6− <file>qml/fake_menu_widget4.qml</file>
7− <file>qml/fake_menu_widget5.qml</file>
8− <file>qml/fake_menu_page1.qml</file>
9− <file>qml/fake_menu_page2.qml</file>
10− <file>qml/fake_menu_page3.qml</file>
11− <file>qml/fake_menu_page4.qml</file>
12− <file>qml/fake_menu_page5.qml</file>
13− </qresource>
14−</RCC>
tests/mocks/Unity/Indicators/qml/fake_menu_page1.qmldeleted−35
@@ -1,35 +0,0 @@
1−/*
2− * Copyright 2013 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import Unity.Indicators 0.1 as Indicators
19−
20−Indicators.FakeMenuPage {
21− id: menu_plugin1
22−
23− Rectangle {
24− id: contents
25− color: "red"
26−
27− height: 150
28− width: 150
29−
30− anchors {
31− horizontalCenter: parent.horizontalCenter
32− verticalCenter: parent.verticalCenter
33− }
34− }
35−}
tests/mocks/Unity/Indicators/qml/fake_menu_page2.qmldeleted−35
@@ -1,35 +0,0 @@
1−/*
2− * Copyright 2013 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import Unity.Indicators 0.1 as Indicators
19−
20−Indicators.FakeMenuPage {
21− id: menu_plugin2
22−
23− Rectangle {
24− id: contents
25− color: "blue"
26−
27− height: 150
28− width: 150
29−
30− anchors {
31− horizontalCenter: parent.horizontalCenter
32− verticalCenter: parent.verticalCenter
33− }
34− }
35−}
tests/mocks/Unity/Indicators/qml/fake_menu_page3.qmldeleted−35
@@ -1,35 +0,0 @@
1−/*
2− * Copyright 2013 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import Unity.Indicators 0.1 as Indicators
19−
20−Indicators.FakeMenuPage {
21− id: menu_plugin3
22−
23− Rectangle {
24− id: contents
25− color: "yellow"
26−
27− height: 150
28− width: 150
29−
30− anchors {
31− horizontalCenter: parent.horizontalCenter
32− verticalCenter: parent.verticalCenter
33− }
34− }
35−}
tests/mocks/Unity/Indicators/qml/fake_menu_page4.qmldeleted−35
@@ -1,35 +0,0 @@
1−/*
2− * Copyright 2013 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import Unity.Indicators 0.1 as Indicators
19−
20−Indicators.FakeMenuPage {
21− id: menu_plugin4
22−
23− Rectangle {
24− id: contents
25− color: "green"
26−
27− height: 150
28− width: 150
29−
30− anchors {
31− horizontalCenter: parent.horizontalCenter
32− verticalCenter: parent.verticalCenter
33− }
34− }
35−}
tests/mocks/Unity/Indicators/qml/fake_menu_page5.qmldeleted−35
@@ -1,35 +0,0 @@
1−/*
2− * Copyright 2013 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import Unity.Indicators 0.1 as Indicators
19−
20−Indicators.FakeMenuPage {
21− id: menu_plugin5
22−
23− Rectangle {
24− id: contents
25− color: "orange"
26−
27− height: 150
28− width: 150
29−
30− anchors {
31− horizontalCenter: parent.horizontalCenter
32− verticalCenter: parent.verticalCenter
33− }
34− }
35−}
tests/mocks/Unity/Indicators/qml/fake_menu_widget1.qmldeleted−23
@@ -1,23 +0,0 @@
1−/*
2− * Copyright 2013 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−
19−Rectangle {
20− width: 40
21− height: 40
22− color : "red"
23−}
tests/mocks/Unity/Indicators/qml/fake_menu_widget2.qmldeleted−23
@@ -1,23 +0,0 @@
1−/*
2− * Copyright 2013 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−
19−Rectangle {
20− width: 40
21− height: 40
22− color : "blue"
23−}
tests/mocks/Unity/Indicators/qml/fake_menu_widget3.qmldeleted−23
@@ -1,23 +0,0 @@
1−/*
2− * Copyright 2013 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−
19−Rectangle {
20− width: 40
21− height: 40
22− color : "yellow"
23−}
tests/mocks/Unity/Indicators/qml/fake_menu_widget4.qmldeleted−23
@@ -1,23 +0,0 @@
1−/*
2− * Copyright 2013 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−
19−Rectangle {
20− width: 40
21− height: 40
22− color : "green"
23−}
tests/mocks/Unity/Indicators/qml/fake_menu_widget5.qmldeleted−23
@@ -1,23 +0,0 @@
1−/*
2− * Copyright 2013 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−
19−Rectangle {
20− width: 40
21− height: 40
22− color : "orange"
23−}
tests/mocks/Unity/Indicators/qmldir−1
@@ -3,5 +3,4 @@ plugin IndicatorsFakeQml
33typeinfo Indicators.qmltypes
44
55IndicatorsModel 0.1 IndicatorsModel.qml
6−FakeMenuPage 0.1 FakeMenuPage.qml
76RootActionState 0.1 RootActionState.qml
tests/mocks/Unity/Launcher/Launcher.qmltypes+13
@@ -85,6 +85,7 @@ Module {
8585 Property { name: "recent"; type: "bool"; isReadonly: true }
8686 Property { name: "progress"; type: "int"; isReadonly: true }
8787 Property { name: "count"; type: "int"; isReadonly: true }
88+ Property { name: "countVisible"; type: "bool"; isReadonly: true }
8889 Property { name: "focused"; type: "bool"; isReadonly: true }
8990 Property {
9091 name: "quickList"
@@ -92,6 +93,14 @@ Module {
9293 isReadonly: true
9394 isPointer: true
9495 }
96+ Signal {
97+ name: "nameChanged"
98+ Parameter { name: "name"; type: "string" }
99+ }
100+ Signal {
101+ name: "iconChanged"
102+ Parameter { name: "icon"; type: "string" }
103+ }
95104 Signal {
96105 name: "pinnedChanged"
97106 Parameter { name: "pinned"; type: "bool" }
@@ -112,6 +121,10 @@ Module {
112121 name: "countChanged"
113122 Parameter { name: "count"; type: "int" }
114123 }
124+ Signal {
125+ name: "countVisibleChanged"
126+ Parameter { name: "countVisible"; type: "bool" }
127+ }
115128 Signal {
116129 name: "focusedChanged"
117130 Parameter { name: "focused"; type: "bool" }
tests/mocks/Unity/Unity.qmltypes+32
@@ -30,6 +30,25 @@ Module {
3030 Parameter { name: "row"; type: "int" }
3131 Parameter { name: "role"; type: "int" }
3232 }
33+ Method {
34+ name: "setCount"
35+ Parameter { name: "count"; type: "int" }
36+ }
37+ Method {
38+ name: "resultModel"
39+ type: "ResultsModel*"
40+ Parameter { name: "row"; type: "int" }
41+ }
42+ Method {
43+ name: "setLayout"
44+ Parameter { name: "row"; type: "int" }
45+ Parameter { name: "layout"; type: "string" }
46+ }
47+ Method {
48+ name: "setHeaderLink"
49+ Parameter { name: "row"; type: "int" }
50+ Parameter { name: "headerLink"; type: "string" }
51+ }
3352 }
3453 Component {
3554 name: "PreviewModel"
@@ -66,6 +85,10 @@ Module {
6685 exports: ["Unity/FakeResultsModel 0.2", "Unity/ResultsModel 0.2"]
6786 isCreatable: false
6887 exportMetaObjectRevisions: [0, 0]
88+ Method {
89+ name: "setResultCount"
90+ Parameter { name: "result_count"; type: "int" }
91+ }
6992 }
7093 Component {
7194 name: "Scope"
@@ -76,6 +99,15 @@ Module {
7699 name: "performQuery"
77100 Parameter { name: "query"; type: "string" }
78101 }
102+ Signal { name: "refreshed" }
103+ Method {
104+ name: "setId"
105+ Parameter { name: "id"; type: "string" }
106+ }
107+ Method {
108+ name: "setName"
109+ Parameter { name: "name"; type: "string" }
110+ }
79111 Method {
80112 name: "setSearchInProgress"
81113 Parameter { name: "inProg"; type: "bool" }
tests/plugins/Unity/Indicators/CMakeLists.txt+1
@@ -40,3 +40,4 @@ indicator_test(indicatorsmodeltest ADDITIONAL_LIBS IndicatorsQml)
4040indicator_test(menucontentactivatortest ADDITIONAL_CPPS ${INDICATORS_DIR}/menucontentactivator.cpp)
4141indicator_test(unitymenumodelstacktest ADDITIONAL_CPPS ${TEST_DIR}/mocks/QMenuModel/unitymenumodel.cpp ${INDICATORS_DIR}/unitymenumodelstack.cpp)
4242indicator_test(rootactionstatetest ADDITIONAL_LIBS IndicatorsQml)
43+indicator_test(sharedunitymenumodeltest ADDITIONAL_LIBS IndicatorsQml)
tests/plugins/Unity/Indicators/sharedunitymenumodeltest.cppnew file+102
@@ -0,0 +1,102 @@
1+/*
2+ * Copyright 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 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+ */
17+
18+#include "sharedunitymenumodel.h"
19+#include "unitymenumodelcache.h"
20+
21+#include <QtTest>
22+#include <unitymenumodel.h>
23+
24+class SharedUnityMenuModelTest : public QObject
25+{
26+ Q_OBJECT
27+
28+ SharedUnityMenuModel* createFullModel(const QByteArray& testId)
29+ {
30+ SharedUnityMenuModel* model = new SharedUnityMenuModel;
31+ model->setBusName("com.canonical." + testId);
32+ model->setMenuObjectPath("/com/canonical/" + testId);
33+ QVariantMap actions;
34+ actions["test"] = QString("/com/canonical/%1/actions").arg(QString(testId));
35+ model->setActions(actions);
36+
37+ return model;
38+ }
39+
40+private Q_SLOTS:
41+
42+ void testCreateModel()
43+ {
44+ QSharedPointer<SharedUnityMenuModel> model(createFullModel("test1"));
45+ QVERIFY(model->model() != nullptr);
46+ }
47+
48+ void testDifferentDataCreatesDifferentModels()
49+ {
50+ QSharedPointer<SharedUnityMenuModel> model1(createFullModel("test1"));
51+ QSharedPointer<SharedUnityMenuModel> model2(createFullModel("test2"));
52+
53+ QVERIFY(model1->model() != model2->model());
54+ }
55+
56+ void testSameDataCreatesSameModels()
57+ {
58+ QSharedPointer<SharedUnityMenuModel> model1(createFullModel("test1"));
59+ QSharedPointer<SharedUnityMenuModel> model2(createFullModel("test1"));
60+
61+ QCOMPARE(model1->model(), model2->model());
62+ }
63+
64+ void testSharedOwnership()
65+ {
66+ QSharedPointer<SharedUnityMenuModel> model1(createFullModel("test1"));
67+ QSharedPointer<SharedUnityMenuModel> model2(createFullModel("test1"));
68+
69+ QCOMPARE(UnityMenuModelCache::singleton()->contains("/com/canonical/test1"), true);
70+ model1.clear();
71+ QCOMPARE(UnityMenuModelCache::singleton()->contains("/com/canonical/test1"), true);
72+ model2.clear();
73+ QCOMPARE(UnityMenuModelCache::singleton()->contains("/com/canonical/test1"), false);
74+ }
75+
76+ // Tests that changing cached model data does not change the model path of others
77+ void testLP1328646()
78+ {
79+ QSharedPointer<SharedUnityMenuModel> model1(createFullModel("test1"));
80+ QSharedPointer<SharedUnityMenuModel> model2(createFullModel("test1"));
81+
82+ model2->setMenuObjectPath("/com/canonical/LP1328646");
83+
84+ QVERIFY(model1->model() != model2->model());
85+ QCOMPARE(model1->model()->menuObjectPath(), QByteArray("/com/canonical/test1"));
86+ QCOMPARE(model2->model()->menuObjectPath(), QByteArray("/com/canonical/LP1328646"));
87+ }
88+
89+ // Tests that the cache is recreated if deleted.
90+ void testDeletedCache()
91+ {
92+ QSharedPointer<SharedUnityMenuModel> model1(createFullModel("test1"));
93+
94+ QCOMPARE(UnityMenuModelCache::singleton()->contains("/com/canonical/test1"), true);
95+ delete UnityMenuModelCache::singleton();
96+ QCOMPARE(UnityMenuModelCache::singleton()->contains("/com/canonical/test1"), false);
97+ }
98+
99+};
100+
101+QTEST_GUILESS_MAIN(SharedUnityMenuModelTest)
102+#include "sharedunitymenumodeltest.moc"
tests/qmltests/CMakeLists.txt+7−8
@@ -19,9 +19,9 @@ set(qmltest_DEFAULT_TARGETS qmluitests)
1919set(qmltest_DEFAULT_NO_ADD_TEST TRUE)
2020set(qmltest_DEFAULT_PROPERTIES ENVIRONMENT "LC_ALL=C")
2121
22−add_qml_test(. Shell ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
23−add_qml_test(. ShellWithPin ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single-pin")
24−add_qml_test(. TabletShell ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full")
22+add_qml_test(. Shell ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single:${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
23+add_qml_test(. ShellWithPin ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single-pin:${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
24+add_qml_test(. TabletShell ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full:${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
2525add_qml_test(Components Background)
2626add_qml_test(Components Carousel)
2727add_qml_test(Components DraggingArea)
@@ -72,14 +72,13 @@ add_qml_test(Launcher Launcher)
7272add_qml_test(Notifications Notifications)
7373add_qml_test(Notifications VisualSnapDecisionsQueue)
7474add_qml_test(Panel ActiveCallHint)
75−add_qml_test(Panel IndicatorRow)
76−add_qml_test(Panel Indicators)
77−add_qml_test(Panel MenuContent)
78−add_qml_test(Panel Panel)
75+add_qml_test(Panel IndicatorRow ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
76+add_qml_test(Panel Indicators ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
77+add_qml_test(Panel MenuContent ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
78+add_qml_test(Panel Panel ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
7979add_qml_test(Panel SearchIndicator)
8080add_qml_test(Panel/Indicators DefaultIndicatorWidget ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
8181add_qml_test(Panel/Indicators DefaultIndicatorPage ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
82−add_qml_test(Panel/Indicators CachedUnityMenuModel ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
8382# These MenuItemFactory tests need the test/mocks/ to come before plugins/
8483add_qml_test(Panel/Indicators MenuItemFactory IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks ${qmltest_DEFAULT_IMPORT_PATHS})
8584add_qml_test(Panel/Indicators MessageMenuItemFactory IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks ${qmltest_DEFAULT_IMPORT_PATHS})
tests/qmltests/Greeter/tst_Clock.qml+51−34
@@ -19,7 +19,7 @@ import QtTest 1.0
1919import ".."
2020import "../../../qml/Greeter"
2121import Ubuntu.Components 0.1
22−import QMenuModel 0.1
22+import Unity.Indicators 0.1 as Indicators
2323import Unity.Test 0.1 as UT
2424
2525Rectangle {
@@ -36,56 +36,73 @@ Rectangle {
3636 }
3737 }
3838
39− UnityMenuModel {
40− id: menuModel
41− modelData: [{
42− "rowData": {
43− "actionState": { "label": Qt.formatTime(new Date("October 13, 1975 11:13:00")) }
44− }
45− }]
39+ function updateDatetimeModelTime(label) {
40+ Indicators.UnityMenuModelCache.setCachedModelData("com.canonical.indicator.datetime",
41+ "/com/canonical/indicator/datetime/phone",
42+ "/com/canonical/indicator/datetime",
43+ [{
44+ "rowData": {
45+ "actionState": { "label": label }
46+ }
47+ }]);
4648 }
4749
4850 UT.UnityTestCase {
4951 name: "Clock"
52+ when: windowShown
5053
5154 function init() {
52− var cachedModel = findChild(clock, "timeModel");
53− verify(cachedModel !== undefined);
54− cachedModel.model = menuModel;
55+ updateDatetimeModelTime(Qt.formatTime(new Date("October 13, 1975 12:14:00")));
56+ clock.visible = true;
5557 }
5658
57− function test_customDate() {
58− var dateObj = new Date("October 13, 1975 11:13:00")
59− var dateString = Qt.formatDate(dateObj, Qt.DefaultLocaleLongDate)
60− var timeString = Qt.formatTime(dateObj)
59+ // Test that the date portion of the clock updates with custom value.
60+ // Time portion is controlled by indicators
61+ function test_updateDate() {
62+ var dateLabel = findChild(clock, "dateLabel");
63+ var timeLabel = findChild(clock, "timeLabel");
6164
62− clock.currentDate = dateObj
63− var dateLabel = findChild(clock, "dateLabel")
64− compare(dateLabel.text, dateString, "Not the expected date")
65− var timeLabel = findChild(clock, "timeLabel")
66− compare(timeLabel.text, timeString, "Not the expected time")
65+ var timeString = Qt.formatTime(new Date("October 13, 1975 12:14:00"));
66+
67+ // initial date.
68+ var dateObj = new Date("October 13, 1975 11:13:00");
69+ var dateString = Qt.formatDate(dateObj, Qt.DefaultLocaleLongDate);
70+ clock.currentDate = dateObj;
71+
72+ compare(dateLabel.text, dateString, "Not the expected date");
73+ compare(timeLabel.text, timeString, "Time should come from indicators");
74+
75+ // update date.
76+ var dateObj2 = new Date("October 14, 1976 13:15:00");
77+ var dateString2 = Qt.formatDate(dateObj2, Qt.DefaultLocaleLongDate);
78+ clock.currentDate = dateObj2;
79+
80+ compare(dateLabel.text, dateString2, "Not the expected date");
81+ compare(timeLabel.text,timeString, "Time should come from indicators");
6782 }
6883
69− function test_dateUpdate() {
70− var dateObj = new Date("October 13, 1975 11:13:00")
71− var dateString = Qt.formatDate(dateObj, Qt.DefaultLocaleLongDate)
72− var timeString = Qt.formatTime(dateObj)
84+ // Test that the date portion of the clock updates with custom value.
85+ // Time portion is controlled by indicators
86+ function test_updateTime() {
87+ var timeLabel = findChild(clock, "timeLabel");
7388
74− clock.visible = false
75− var timeModel = findInvisibleChild(clock, "timeModel")
89+ var timeString1 = Qt.formatTime(new Date("October 13, 1975 11:15:00"));
90+ var timeString2 = Qt.formatTime(new Date("October 14, 1976 12:16:00"));
7691
77− compare(timeModel.menuObjectPath, "", "Clock shouldn't be connected to Indicators when not visible.")
92+ updateDatetimeModelTime(timeString1);
93+ compare(timeLabel.text, timeString1, "Time should come from indicators");
7894
79− clock.currentDate = dateObj
95+ updateDatetimeModelTime(timeString2);
96+ compare(timeLabel.text, timeString2, "Time should come from indicators");
97+ }
8098
81− var dateLabel = findChild(clock, "dateLabel")
82− compare(dateLabel.text, dateString, "Not the expected date")
83− var timeLabel = findChild(clock, "timeLabel")
84− compare(timeLabel.text, timeString, "Not the expected time")
99+ function test_indicatorDisconnect() {
100+ clock.visible = false
101+ var timeModel = findInvisibleChild(clock, "timeModel")
102+ compare(timeModel.menuObjectPath, "", "Clock shouldn't be connected to Indicators when not visible.")
85103
86104 clock.visible = true
87−
88− verify(timeModel.menuObjectPath != "", "Should be connected to Indicators.")
105+ verify(timeModel.menuObjectPath !== "", "Should be connected to Indicators.")
89106 }
90107 }
91108}
tests/qmltests/Panel/Indicators/tst_CachedUnityMenuModel.qmldeleted−137
@@ -1,137 +0,0 @@
1−/*
2− * Copyright 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−import QtQuick 2.0
18−import QtTest 1.0
19−import Unity.Test 0.1 as UT
20−import QMenuModel 0.1
21−import Unity.Indicators 0.1 as Indicators
22−import "../../../../qml/Panel/Indicators"
23−
24−Item {
25− id: root
26− width: units.gu(40)
27− height: units.gu(70)
28−
29− Component {
30− id: model
31− CachedUnityMenuModel {}
32− }
33−
34− UT.UnityTestCase {
35− name: "CachedUnityMenuModel"
36− when: windowShown
37−
38− function cleanup() {
39− doGC();
40− }
41−
42− function doGC() {
43− // need to put some wait cycles here to get gc going properly.
44− wait(10);
45− gc();
46− wait(10);
47− }
48−
49− function test_createDifferent() {
50− var cachedObject = model.createObject(null,
51− {
52− "busName": "com.canonical.test1",
53− "menuObjectPath": "/com/canonical/test1",
54− "actionsObjectPath": "/com/canonical/test1"
55− });
56−
57− var cachedObject2 = model.createObject(null,
58− {
59− "busName": "com.canonical.test2",
60− "menuObjectPath": "/com/canonical/test2",
61− "actionsObjectPath": "/com/canonical/test2"
62− });
63−
64− verify(cachedObject.model !== cachedObject2.model);
65− }
66−
67− function test_createSame() {
68− var cachedObject = model.createObject(null,
69− {
70− "busName": "com.canonical.test3",
71− "menuObjectPath": "/com/canonical/test3",
72− "actionsObjectPath": "/com/canonical/test3"
73− });
74−
75− var cachedObject2 = model.createObject(null,
76− {
77− "busName": "com.canonical.test3",
78− "menuObjectPath": "/com/canonical/test3",
79− "actionsObjectPath": "/com/canonical/test3"
80− });
81−
82− verify(cachedObject.model === cachedObject2.model);
83− }
84−
85− // Tests that changing cached model data does not change the model path of others
86− function test_lp1328646() {
87− var cachedObject = model.createObject(null,
88− {
89− "busName": "com.canonical.test4",
90− "menuObjectPath": "/com/canonical/test4",
91− "actionsObjectPath": "/com/canonical/test4"
92− });
93−
94− var cachedObject2 = model.createObject(null,
95− {
96− "busName": "com.canonical.test4",
97− "menuObjectPath": "/com/canonical/test4",
98− "actionsObjectPath": "/com/canonical/test4"
99− });
100−
101− cachedObject.menuObjectPath = "/com/canonical/test5";
102− compare(cachedObject.model.menuObjectPath, "/com/canonical/test5");
103− compare(cachedObject2.model.menuObjectPath, "/com/canonical/test4");
104−
105− verify(cachedObject.model !== cachedObject2.model);
106− }
107−
108− function createAndDestroy(test) {
109− var cachedObject = model.createObject(null,
110− {
111− "busName": "com.canonical."+test,
112− "menuObjectPath": "/com/canonical/"+test,
113− "actionsObjectPath": "/com/canonical/"+test
114− });
115− var cachedObject2 = model.createObject(null,
116− {
117− "busName": "com.canonical."+test,
118− "menuObjectPath": "/com/canonical/"+test,
119− "actionsObjectPath": "/com/canonical/"+test
120− });
121− cachedObject.destroy();
122− return cachedObject2;
123− }
124−
125− function test_destroyAllDeletesModel() {
126− createAndDestroy("test6");
127− doGC();
128− compare(Indicators.UnityMenuModelCache.contains("/com/canonical/test6"), false);
129− }
130−
131− function test_destroyPartialKeepsModel() {
132− var model = createAndDestroy("test7");
133− doGC();
134− compare(Indicators.UnityMenuModelCache.contains("/com/canonical/test7"), true);
135− }
136− }
137−}
tests/qmltests/Panel/Indicators/tst_DefaultIndicatorPage.qml+16−19
@@ -17,7 +17,7 @@
1717import QtQuick 2.0
1818import QtTest 1.0
1919import Unity.Test 0.1 as UT
20−import QMenuModel 0.1
20+import Unity.Indicators 0.1 as Indicators
2121import "../../../../qml/Panel/Indicators"
2222
2323Item {
@@ -25,18 +25,14 @@ Item {
2525 width: units.gu(40)
2626 height: units.gu(70)
2727
28− DefaultIndicatorPage {
28+ DefaultIndicatorPage {
2929 id: page
30−
3130 anchors.fill: parent
3231
33− menuModel: UnityMenuModel {}
34− busName: "test"
35− actionsObjectPath: "test"
36− menuObjectPath: "test"
37−
3832 identifier: "test-indicator"
39− rootMenuType: "com.canonical.indicator.root"
33+ busName: "com.caninical.indicator.test"
34+ actionsObjectPath: "/com/canonical/indicator/test"
35+ menuObjectPath: "/com/canonical/indicator/test"
4036 }
4137
4238 property var fullMenuData: [{
@@ -113,29 +109,30 @@ Item {
113109 "submenu": []
114110 }]; // end row 1
115111
112+ function initializeMenuData(data) {
113+ Indicators.UnityMenuModelCache.setCachedModelData("com.canonical.indicator.test",
114+ "/com/canonical/indicator/test",
115+ "/com/canonical/indicator/test",
116+ data);
117+ }
118+
116119 UT.UnityTestCase {
117120 name: "DefaultIndicatorPage"
118121
119122 function init() {
120− var mainMenu = findChild(page, "mainMenu");
121− page.menuModel.modelData = [];
122− verify(mainMenu.model !== null);
123+ initializeMenuData([]);
123124 }
124125
125126 function test_reloadData() {
126127 var mainMenu = findChild(page, "mainMenu");
127128
128− page.menuModel.modelData = [];
129129 tryCompare(mainMenu, "count", 0);
130130
131− page.menuModel.modelData = fullMenuData;
131+ initializeMenuData(fullMenuData);
132132 tryCompare(mainMenu, "count", 3);
133133
134− page.menuModel.modelData = [];
134+ initializeMenuData([]);
135135 tryCompare(mainMenu, "count", 0);
136−
137− page.menuModel.modelData = fullMenuData;
138− tryCompare(mainMenu, "count", 3);
139136 }
140137
141138 function test_traverse_rootMenuType_data() {
@@ -147,7 +144,7 @@ Item {
147144
148145 function test_traverse_rootMenuType(data) {
149146 page.rootMenuType = data.rootMenuType;
150− page.menuModel.modelData = fullMenuData;
147+ initializeMenuData(fullMenuData);
151148
152149 var mainMenu = findChild(page, "mainMenu");
153150 tryCompare(mainMenu, "count", data.expectedCount);
tests/qmltests/Panel/Indicators/tst_DefaultIndicatorWidget.qml−8
@@ -33,7 +33,6 @@ Item {
3333 top: parent.top
3434 }
3535
36− menuModel: UnityMenuModel {}
3736 busName: "test"
3837 actionsObjectPath: "test"
3938 deviceMenuObjectPath: "test"
@@ -48,13 +47,6 @@ Item {
4847 name: "DefaultIndicatorWidget"
4948 when: windowShown
5049
51− function init() {
52− widget.rootActionState.icons = [];
53− widget.rootActionState.leftLabel = "";
54− widget.rootActionState.rightLabel = "";
55− waitForRendering(widget)
56− }
57−
5850 // FIXME: add tests
5951 }
6052}
tests/qmltests/Panel/tst_IndicatorItem.qml+1−1
@@ -43,7 +43,7 @@ Rectangle {
4343
4444 function test_empty() {
4545 compare(indicatorItem.indicatorVisible, false, "IndicatorItem should not be visible.");
46− indicatorItem.widgetSource = "qrc:/tests/indciators/qml/fake_menu_widget1.qml";
46+ indicatorItem.widgetSource = "../../../qml/Panel/Indicators/DefaultIndicatorWidget.qml";
4747 tryCompare(indicatorItem, "indicatorVisible", true);
4848 }
4949 }
tests/qmltests/Panel/tst_IndicatorRow.qml+17−19
@@ -30,15 +30,6 @@ Item {
3030 width: units.gu(40)
3131 height: units.gu(60)
3232
33− function init_test()
34− {
35− indicatorModel.load("test1");
36−
37− indicatorRow.state = "initial";
38− indicatorRow.setCurrentItemIndex(-1);
39− indicatorRow.unitProgress = 0.0;
40− }
41−
4233 PanelBackground {
4334 anchors.fill: indicatorRow
4435 }
@@ -63,20 +54,33 @@ Item {
6354 name: "IndicatorRow"
6455 when: windowShown
6556
57+ function init() {
58+ indicatorModel.load("test1");
59+
60+ indicatorRow.state = "initial";
61+ indicatorRow.setCurrentItemIndex(-1);
62+ indicatorRow.unitProgress = 0.0;
63+ }
64+
6665 function get_indicator_item(index) {
6766 return findChild(indicatorRow.row, "item" + index);
6867 }
6968
7069 function test_set_current_item() {
71− init_test();
7270 indicatorRow.setCurrentItemIndex(0);
73− compare(indicatorRow.indicatorsModel.data(indicatorRow.currentItemIndex, Indicators.IndicatorsModelRole.Identifier), "indicator-fake1", "Incorrect item at position 0");
71+ compare(indicatorRow.indicatorsModel.data(indicatorRow.currentItemIndex, Indicators.IndicatorsModelRole.Identifier),
72+ "indicator-fake1",
73+ "Incorrect item at position 0");
7474
7575 indicatorRow.setCurrentItemIndex(1);
76− compare(indicatorRow.indicatorsModel.data(indicatorRow.currentItemIndex, Indicators.IndicatorsModelRole.Identifier), "indicator-fake2", "Incorrect item at position 1");
76+ compare(indicatorRow.indicatorsModel.data(indicatorRow.currentItemIndex, Indicators.IndicatorsModelRole.Identifier),
77+ "indicator-fake2",
78+ "Incorrect item at position 1");
7779
7880 indicatorRow.setCurrentItemIndex(2);
79− compare(indicatorRow.indicatorsModel.data(indicatorRow.currentItemIndex, Indicators.IndicatorsModelRole.Identifier), "indicator-fake3", "Incorrect item at position 2");
81+ compare(indicatorRow.indicatorsModel.data(indicatorRow.currentItemIndex, Indicators.IndicatorsModelRole.Identifier),
82+ "indicator-fake3",
83+ "Incorrect item at position 2");
8084 }
8185
8286 function test_highlight_data() {
@@ -93,8 +97,6 @@ Item {
9397 }
9498
9599 function test_highlight(data) {
96− init_test();
97−
98100 indicatorRow.unitProgress = data.progress;
99101 indicatorRow.setCurrentItemIndex(data.index);
100102
@@ -119,8 +121,6 @@ Item {
119121 }
120122
121123 function test_opacity(data) {
122− init_test();
123−
124124 indicatorRow.unitProgress = data.progress;
125125 indicatorRow.setCurrentItemIndex(data.index);
126126
@@ -145,8 +145,6 @@ Item {
145145 }
146146
147147 function test_dimmed(data) {
148− init_test();
149−
150148 indicatorRow.unitProgress = data.progress;
151149 indicatorRow.setCurrentItemIndex(data.index);
152150
tests/qmltests/Panel/tst_Indicators.qml+1
@@ -158,6 +158,7 @@ Item {
158158 function init_invisible_indicator(identifier) {
159159 tryCompareFunction(function() { return findChild(indicators, identifier+"-delegate") !== undefined }, true);
160160 var item = findChild(indicators, identifier+"-delegate");
161+ verify(item !== null);
161162
162163 item.enabled = false;
163164 }
tests/qmltests/Panel/tst_MenuContent.qml−8
@@ -26,14 +26,6 @@ Item {
2626 width: units.gu(40)
2727 height: units.gu(70)
2828
29− property var indicator_status: {
30− 'indicator-fake1-page': { 'started': false, 'reset': 0 },
31− 'indicator-fake2-page': { 'started': false, 'reset': 0 },
32− 'indicator-fake3-page': { 'started': false, 'reset': 0 },
33− 'indicator-fake4-page': { 'started': false, 'reset': 0 },
34− 'indicator-fake5-page': { 'started': false, 'reset': 0 }
35− }
36−
3729 // Dummy objects
3830 Item { id: greeter }
3931 Item { id: handle }
tests/qmltests/tst_Shell.qml+2
@@ -65,6 +65,8 @@ Row {
6565 property bool itemDestroyed: false
6666 sourceComponent: Component {
6767 Shell {
68+ property string indicatorProfile: "phone"
69+
6870 Component.onDestruction: {
6971 shellLoader.itemDestroyed = true;
7072 }
tests/qmltests/tst_ShellWithPin.qml+2
@@ -61,6 +61,8 @@ Item {
6161 property bool itemDestroyed: false
6262 sourceComponent: Component {
6363 Shell {
64+ property string indicatorProfile: "phone"
65+
6466 Component.onDestruction: {
6567 shellLoader.itemDestroyed = true
6668 }
tests/qmltests/tst_TabletShell.qml+2
@@ -57,6 +57,8 @@ Row {
5757 property bool itemDestroyed: false
5858 sourceComponent: Component {
5959 Shell {
60+ property string indicatorProfile: "phone"
61+
6062 Component.onDestruction: {
6163 shellLoader.itemDestroyed = true
6264 }