on xenial help sign in
remove qml ownership confusion for caching unitymenumodels Fixes: 1368856
41cc225Nick Dedekind
plugins/AccountsService/AccountsService.qmltypes+2
@@ -23,6 +23,8 @@ Module {
23 }
23 }
24 Property { name: "user"; type: "string" }
24 Property { name: "user"; type: "string" }
25 Property { name: "demoEdges"; type: "bool" }
25 Property { name: "demoEdges"; type: "bool" }
26+ Property { name: "enableLauncherWhileLocked"; type: "bool"; isReadonly: true }
27+ Property { name: "enableIndicatorsWhileLocked"; type: "bool"; isReadonly: true }
26 Property { name: "backgroundFile"; type: "string"; isReadonly: true }
28 Property { name: "backgroundFile"; type: "string"; isReadonly: true }
27 Property { name: "statsWelcomeScreen"; type: "bool"; isReadonly: true }
29 Property { name: "statsWelcomeScreen"; type: "bool"; isReadonly: true }
28 Property { name: "passwordDisplayHint"; type: "PasswordDisplayHint"; isReadonly: true }
30 Property { name: "passwordDisplayHint"; type: "PasswordDisplayHint"; isReadonly: true }
plugins/Dash/Dash.qmltypes+3
@@ -40,9 +40,12 @@ Module {
40 Property { name: "forceNoClip"; type: "bool" }
40 Property { name: "forceNoClip"; type: "bool" }
41 Property { name: "stickyHeaderHeight"; type: "int"; isReadonly: true }
41 Property { name: "stickyHeaderHeight"; type: "int"; isReadonly: true }
42 Property { name: "headerItemShownHeight"; type: "double"; isReadonly: true }
42 Property { name: "headerItemShownHeight"; type: "double"; isReadonly: true }
43+ Property { name: "cacheBuffer"; type: "double" }
43 Signal { name: "headerChanged" }
44 Signal { name: "headerChanged" }
44 Method { name: "positionAtBeginning" }
45 Method { name: "positionAtBeginning" }
45 Method { name: "showHeader" }
46 Method { name: "showHeader" }
47+ Method { name: "firstCreatedIndex"; type: "int" }
48+ Method { name: "createdItemCount"; type: "int" }
46 Method {
49 Method {
47 name: "item"
50 name: "item"
48 type: "QQuickItem*"
51 type: "QQuickItem*"
plugins/LightDM/LightDM.qmltypes+1
@@ -37,6 +37,7 @@ Module {
37 Signal { name: "isActiveChanged" }
37 Signal { name: "isActiveChanged" }
38 Signal { name: "isAuthenticatedChanged" }
38 Signal { name: "isAuthenticatedChanged" }
39 Signal { name: "showGreeter" }
39 Signal { name: "showGreeter" }
40+ Signal { name: "hideGreeter" }
40 Signal {
41 Signal {
41 name: "requestAuthenticationUser"
42 name: "requestAuthenticationUser"
42 Parameter { name: "user"; type: "string" }
43 Parameter { name: "user"; type: "string" }
plugins/Ubuntu/Payments/Payments.qmltypes+1
@@ -37,6 +37,7 @@ Module {
37 Parameter { name: "error"; type: "string" }
37 Parameter { name: "error"; type: "string" }
38 }
38 }
39 Signal { name: "purchaseCompleted" }
39 Signal { name: "purchaseCompleted" }
40+ Signal { name: "purchaseCancelled" }
40 Method { name: "start" }
41 Method { name: "start" }
41 }
42 }
42}
43}
plugins/Unity/DashCommunicator/DashCommunicator.qmltypes+16−3
@@ -9,14 +9,14 @@ import QtQuick.tooling 1.1
9Module {
9Module {
10 Component {
10 Component {
11 name: "DashCommunicator"
11 name: "DashCommunicator"
12− prototype: "QObject"
12+ prototype: "QThread"
13 exports: ["Unity.DashCommunicator/DashCommunicator 0.1"]
13 exports: ["Unity.DashCommunicator/DashCommunicator 0.1"]
14 exportMetaObjectRevisions: [0]
14 exportMetaObjectRevisions: [0]
15 Method {
15 Method {
16 name: "setCurrentScope"
16 name: "setCurrentScope"
17 Parameter { name: "scopeId"; type: "string" }
17 Parameter { name: "scopeId"; type: "string" }
18 Parameter { name: "animate"; type: "bool" }
18 Parameter { name: "animate"; type: "bool" }
19− Parameter { name: "reset"; type: "bool" }
19+ Parameter { name: "isSwipe"; type: "bool" }
20 }
20 }
21 }
21 }
22 Component {
22 Component {
@@ -28,7 +28,20 @@ Module {
28 name: "setCurrentScopeRequested"
28 name: "setCurrentScopeRequested"
29 Parameter { name: "scopeId"; type: "string" }
29 Parameter { name: "scopeId"; type: "string" }
30 Parameter { name: "animate"; type: "bool" }
30 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" }
32 }
42 }
43+ Method { name: "start" }
44+ Method { name: "terminate" }
45+ Method { name: "quit" }
33 }
46 }
34}
47}
plugins/Unity/Indicators/CMakeLists.txt+1
@@ -24,6 +24,7 @@ set(IndicatorsQML_SOURCES
24 modelprinter.cpp
24 modelprinter.cpp
25 plugin.cpp
25 plugin.cpp
26 rootactionstate.cpp
26 rootactionstate.cpp
27+ sharedunitymenumodel.cpp
27 unitymenumodelcache.cpp
28 unitymenumodelcache.cpp
28 unitymenumodelstack.cpp
29 unitymenumodelstack.cpp
29 visibleindicatorsmodel.cpp
30 visibleindicatorsmodel.cpp
plugins/Unity/Indicators/Indicators.qmltypes+10−7
@@ -209,6 +209,16 @@ Module {
209 Signal { name: "updated" }
209 Signal { name: "updated" }
210 Signal { name: "indexChanged" }
210 Signal { name: "indexChanged" }
211 }
211 }
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+ }
212 Component {
222 Component {
213 name: "UnityMenuModelCache"
223 name: "UnityMenuModelCache"
214 prototype: "QObject"
224 prototype: "QObject"
@@ -216,13 +226,6 @@ Module {
216 isCreatable: false
226 isCreatable: false
217 isSingleton: true
227 isSingleton: true
218 exportMetaObjectRevisions: [0]
228 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− }
226 Method {
229 Method {
227 name: "contains"
230 name: "contains"
228 type: "bool"
231 type: "bool"
plugins/Unity/Indicators/plugin.cpp+8−2
@@ -30,18 +30,23 @@
30#include "menucontentactivator.h"
30#include "menucontentactivator.h"
31#include "modelprinter.h"
31#include "modelprinter.h"
32#include "rootactionstate.h"
32#include "rootactionstate.h"
33+#include "sharedunitymenumodel.h"
33#include "unitymenumodelcache.h"
34#include "unitymenumodelcache.h"
34#include "unitymenumodelstack.h"
35#include "unitymenumodelstack.h"
35#include "visibleindicatorsmodel.h"
36#include "visibleindicatorsmodel.h"
36
37
38+#include <unitymenumodel.h>
39+
37static QObject* menuModelCacheSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
40static QObject* menuModelCacheSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
38 Q_UNUSED(engine);
41 Q_UNUSED(engine);
39 Q_UNUSED(scriptEngine);
42 Q_UNUSED(scriptEngine);
40− return new UnityMenuModelCache;
43+ return UnityMenuModelCache::singleton();
41}
44}
42
45
43−void Indicators2Plugin::registerTypes(const char *uri)
46+void IndicatorsPlugin::registerTypes(const char *uri)
44{
47{
48+ qRegisterMetaType<UnityMenuModel*>("UnityMenuModel*");
49+
45 qmlRegisterType<IndicatorsManager>(uri, 0, 1, "IndicatorsManager");
50 qmlRegisterType<IndicatorsManager>(uri, 0, 1, "IndicatorsManager");
46 qmlRegisterType<IndicatorsModel>(uri, 0, 1, "IndicatorsModel");
51 qmlRegisterType<IndicatorsModel>(uri, 0, 1, "IndicatorsModel");
47 qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
52 qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
@@ -49,6 +54,7 @@ void Indicators2Plugin::registerTypes(const char *uri)
49 qmlRegisterType<RootActionState>(uri, 0, 1, "RootActionState");
54 qmlRegisterType<RootActionState>(uri, 0, 1, "RootActionState");
50 qmlRegisterType<ModelPrinter>(uri, 0, 1, "ModelPrinter");
55 qmlRegisterType<ModelPrinter>(uri, 0, 1, "ModelPrinter");
51 qmlRegisterType<VisibleIndicatorsModel>(uri, 0, 1, "VisibleIndicatorsModel");
56 qmlRegisterType<VisibleIndicatorsModel>(uri, 0, 1, "VisibleIndicatorsModel");
57+ qmlRegisterType<SharedUnityMenuModel>(uri, 0, 1, "SharedUnityMenuModel");
52
58
53 qmlRegisterSingletonType<UnityMenuModelCache>(uri, 0, 1, "UnityMenuModelCache", menuModelCacheSingleton);
59 qmlRegisterSingletonType<UnityMenuModelCache>(uri, 0, 1, "UnityMenuModelCache", menuModelCacheSingleton);
54
60
plugins/Unity/Indicators/plugin.h+1−1
@@ -22,7 +22,7 @@
22
22
23#include <QtQml/QQmlExtensionPlugin>
23#include <QtQml/QQmlExtensionPlugin>
24
24
25−class Indicators2Plugin : public QQmlExtensionPlugin
25+class IndicatorsPlugin : public QQmlExtensionPlugin
26{
26{
27 Q_OBJECT
27 Q_OBJECT
28 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
28 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 @@
20#include "unitymenumodelcache.h"
20#include "unitymenumodelcache.h"
21#include <unitymenumodel.h>
21#include <unitymenumodel.h>
22
22
23−UnityMenuModelCache::UnityMenuModelCache(QObject* parent)
23+#include <QQmlEngine>
24− : QObject(parent)
24+
25+QPointer<UnityMenuModelCache> UnityMenuModelCache::theCache = nullptr;
26+
27+UnityMenuModelCache* UnityMenuModelCache::singleton()
25{
28{
29+ if (theCache.isNull()) {
30+ theCache = new UnityMenuModelCache();
31+ }
32+ return theCache.data();
26}
33}
27
34
28−UnityMenuModelCache::~UnityMenuModelCache()
35+UnityMenuModelCache::UnityMenuModelCache(QObject* parent)
36+ : QObject(parent)
29{
37{
30}
38}
31
39
32−UnityMenuModel* UnityMenuModelCache::model(const QByteArray& bus,
40+QSharedPointer<UnityMenuModel> UnityMenuModelCache::model(const QByteArray& bus,
33− const QByteArray& path,
41+ const QByteArray& path,
34− const QVariantMap& actions)
42+ const QVariantMap& actions)
35{
43{
36 if (m_registry.contains(path))
44 if (m_registry.contains(path))
37 return m_registry[path];
45 return m_registry[path];
38
46
39− UnityMenuModel* menuModel = new UnityMenuModel;
47+ UnityMenuModel* model = new UnityMenuModel;
48+ QQmlEngine::setObjectOwnership(model, QQmlEngine::CppOwnership);
49+
50+ QSharedPointer<UnityMenuModel> menuModel(model);
40− connect(menuModel, &QObject::destroyed, this, [menuModel, this](QObject*) {
51+ connect(model, &QObject::destroyed, this, [this] {
41− QList<QByteArray> keys = m_registry.keys(menuModel);
52+ QMutableHashIterator<QByteArray, QWeakPointer<UnityMenuModel>> iter(m_registry);
42− Q_FOREACH(const QByteArray& key, keys) {
53+ while(iter.hasNext()) {
54+ auto keyVal = iter.next();
55+ if (keyVal.value().isNull()) {
43− m_registry.remove(key);
56+ iter.remove();
57+ break;
58+ }
44 }
59 }
45 });
60 });
46− m_registry[path] = menuModel;
61+ m_registry[path] = menuModel.toWeakRef();
47
62
48 menuModel->setBusName(bus);
63 menuModel->setBusName(bus);
49 menuModel->setMenuObjectPath(path);
64 menuModel->setMenuObjectPath(path);
plugins/Unity/Indicators/unitymenumodelcache.h+13−7
@@ -24,6 +24,8 @@
24
24
25#include <QObject>
25#include <QObject>
26#include <QHash>
26#include <QHash>
27+#include <QPointer>
28+#include <QWeakPointer>
27
29
28class UnityMenuModel;
30class UnityMenuModel;
29
31
@@ -32,15 +34,19 @@ class UNITYINDICATORS_EXPORT UnityMenuModelCache : public QObject
32 Q_OBJECT
34 Q_OBJECT
33public:
35public:
34 UnityMenuModelCache(QObject*parent=nullptr);
36 UnityMenuModelCache(QObject*parent=nullptr);
35− ~UnityMenuModelCache();
36
37
37− Q_INVOKABLE UnityMenuModel* model(const QByteArray& bus,
38+ static UnityMenuModelCache* singleton();
38− const QByteArray& path,
39− const QVariantMap& actions);
40− Q_INVOKABLE bool contains(const QByteArray& path);
41
39
42−private:
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:
43− QHash<QByteArray, UnityMenuModel*> m_registry;
48+ QHash<QByteArray, QWeakPointer<UnityMenuModel>> m_registry;
49+ static QPointer<UnityMenuModelCache> theCache;
44};
50};
45
51
46#endif // UNITYMENUMODELCACHE_H
52#endif // UNITYMENUMODELCACHE_H
plugins/Unity/Launcher/Launcher.qmltypes+17−12
@@ -13,14 +13,6 @@ Module {
13 exports: ["Unity.Launcher/LauncherItem 0.1"]
13 exports: ["Unity.Launcher/LauncherItem 0.1"]
14 isCreatable: false
14 isCreatable: false
15 exportMetaObjectRevisions: [0]
15 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− }
24 }
16 }
25 Component {
17 Component {
26 name: "LauncherModel"
18 name: "LauncherModel"
@@ -29,6 +21,10 @@ Module {
29 isCreatable: false
21 isCreatable: false
30 isSingleton: true
22 isSingleton: true
31 exportMetaObjectRevisions: [0]
23 exportMetaObjectRevisions: [0]
24+ Method {
25+ name: "requestRemove"
26+ Parameter { name: "appId"; type: "string" }
27+ }
32 Method {
28 Method {
33 name: "get"
29 name: "get"
34 type: "unity::shell::launcher::LauncherItemInterface*"
30 type: "unity::shell::launcher::LauncherItemInterface*"
@@ -48,10 +44,6 @@ Module {
48 name: "pin"
44 name: "pin"
49 Parameter { name: "appId"; type: "string" }
45 Parameter { name: "appId"; type: "string" }
50 }
46 }
51− Method {
52− name: "requestRemove"
53− Parameter { name: "appId"; type: "string" }
54− }
55 Method {
47 Method {
56 name: "quickListActionInvoked"
48 name: "quickListActionInvoked"
57 Parameter { name: "appId"; type: "string" }
49 Parameter { name: "appId"; type: "string" }
@@ -88,6 +80,7 @@ Module {
88 Property { name: "recent"; type: "bool"; isReadonly: true }
80 Property { name: "recent"; type: "bool"; isReadonly: true }
89 Property { name: "progress"; type: "int"; isReadonly: true }
81 Property { name: "progress"; type: "int"; isReadonly: true }
90 Property { name: "count"; type: "int"; isReadonly: true }
82 Property { name: "count"; type: "int"; isReadonly: true }
83+ Property { name: "countVisible"; type: "bool"; isReadonly: true }
91 Property { name: "focused"; type: "bool"; isReadonly: true }
84 Property { name: "focused"; type: "bool"; isReadonly: true }
92 Property {
85 Property {
93 name: "quickList"
86 name: "quickList"
@@ -95,6 +88,14 @@ Module {
95 isReadonly: true
88 isReadonly: true
96 isPointer: true
89 isPointer: true
97 }
90 }
91+ Signal {
92+ name: "nameChanged"
93+ Parameter { name: "name"; type: "string" }
94+ }
95+ Signal {
96+ name: "iconChanged"
97+ Parameter { name: "icon"; type: "string" }
98+ }
98 Signal {
99 Signal {
99 name: "pinnedChanged"
100 name: "pinnedChanged"
100 Parameter { name: "pinned"; type: "bool" }
101 Parameter { name: "pinned"; type: "bool" }
@@ -115,6 +116,10 @@ Module {
115 name: "countChanged"
116 name: "countChanged"
116 Parameter { name: "count"; type: "int" }
117 Parameter { name: "count"; type: "int" }
117 }
118 }
119+ Signal {
120+ name: "countVisibleChanged"
121+ Parameter { name: "countVisible"; type: "bool" }
122+ }
118 Signal {
123 Signal {
119 name: "focusedChanged"
124 name: "focusedChanged"
120 Parameter { name: "focused"; type: "bool" }
125 Parameter { name: "focused"; type: "bool" }
plugins/Unity/Session/Session.qmltypes+10
@@ -34,4 +34,14 @@ Module {
34 Method { name: "RequestReboot" }
34 Method { name: "RequestReboot" }
35 Method { name: "RequestShutdown" }
35 Method { name: "RequestShutdown" }
36 }
36 }
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+ }
37}
47}
plugins/Utils/Utils.qmltypes+6
@@ -106,6 +106,12 @@ Module {
106 Parameter { name: "row"; type: "int" }
106 Parameter { name: "row"; type: "int" }
107 }
107 }
108 }
108 }
109+ Component {
110+ name: "RelativeTimeFormatter"
111+ prototype: "TimeFormatter"
112+ exports: ["Utils/RelativeTimeFormatter 0.1"]
113+ exportMetaObjectRevisions: [0]
114+ }
109 Component {
115 Component {
110 name: "TimeFormatter"
116 name: "TimeFormatter"
111 prototype: "QObject"
117 prototype: "QObject"
qml/Greeter/Clock.qml+9−9
@@ -34,21 +34,21 @@ Item {
34 }
34 }
35 }
35 }
36
36
37− CachedUnityMenuModel {
37+ Indicators.SharedUnityMenuModel {
38 id: timeModel
38 id: timeModel
39 objectName: "timeModel"
39 objectName: "timeModel"
40
40
41 busName: "com.canonical.indicator.datetime"
41 busName: "com.canonical.indicator.datetime"
42− actionsObjectPath: "/com/canonical/indicator/datetime"
42+ actions: { "indicator": "/com/canonical/indicator/datetime" }
43 menuObjectPath: clock.visible ? "/com/canonical/indicator/datetime/phone" : ""
43 menuObjectPath: clock.visible ? "/com/canonical/indicator/datetime/phone" : ""
44+ }
44
45
45− Indicators.RootActionState {
46+ Indicators.RootActionState {
46− menu: timeModel.model
47+ menu: timeModel.model
47− onUpdated: {
48+ onUpdated: {
48− if (timeLabel.text != rightLabel) {
49+ if (timeLabel.text != rightLabel) {
49− timeLabel.text = rightLabel;
50+ if (rightLabel != "") timeLabel.text = rightLabel;
50− clock.currentDate = new Date();
51+ clock.currentDate = new Date();
51− }
52 }
52 }
53 }
53 }
54 }
54 }
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 {
37 property alias menuModel: cachedModel.model
37 property alias menuModel: cachedModel.model
38 property alias rootActionState: rootAction
38 property alias rootActionState: rootAction
39
39
40− CachedUnityMenuModel {
40+ SharedUnityMenuModel {
41 id: cachedModel
41 id: cachedModel
42 busName: indicatorItem.busName
42 busName: indicatorItem.busName
43− actionsObjectPath: indicatorItem.actionsObjectPath
43+ actions: { "indicator": indicatorItem.actionsObjectPath }
44 menuObjectPath: indicatorItem.deviceMenuObjectPath
44 menuObjectPath: indicatorItem.deviceMenuObjectPath
45 }
45 }
46
46
tests/mocks/AccountsService/AccountsService.qmltypes+2
@@ -23,6 +23,8 @@ Module {
23 }
23 }
24 Property { name: "user"; type: "string" }
24 Property { name: "user"; type: "string" }
25 Property { name: "demoEdges"; type: "bool" }
25 Property { name: "demoEdges"; type: "bool" }
26+ Property { name: "enableLauncherWhileLocked"; type: "bool" }
27+ Property { name: "enableIndicatorsWhileLocked"; type: "bool" }
26 Property { name: "backgroundFile"; type: "string" }
28 Property { name: "backgroundFile"; type: "string" }
27 Property { name: "statsWelcomeScreen"; type: "bool" }
29 Property { name: "statsWelcomeScreen"; type: "bool" }
28 Property { name: "passwordDisplayHint"; type: "PasswordDisplayHint"; isReadonly: true }
30 Property { name: "passwordDisplayHint"; type: "PasswordDisplayHint"; isReadonly: true }
tests/mocks/LightDM/LightDM.qmltypes+1
@@ -37,6 +37,7 @@ Module {
37 Signal { name: "isActiveChanged" }
37 Signal { name: "isActiveChanged" }
38 Signal { name: "isAuthenticatedChanged" }
38 Signal { name: "isAuthenticatedChanged" }
39 Signal { name: "showGreeter" }
39 Signal { name: "showGreeter" }
40+ Signal { name: "hideGreeter" }
40 Signal {
41 Signal {
41 name: "requestAuthenticationUser"
42 name: "requestAuthenticationUser"
42 Parameter { name: "user"; type: "string" }
43 Parameter { name: "user"; type: "string" }
tests/mocks/QMenuModel/QMenuModel.qmltypes+1−1
@@ -18,12 +18,12 @@ Module {
18 prototype: "QAbstractListModel"
18 prototype: "QAbstractListModel"
19 exports: ["QMenuModel/UnityMenuModel 0.1"]
19 exports: ["QMenuModel/UnityMenuModel 0.1"]
20 exportMetaObjectRevisions: [0]
20 exportMetaObjectRevisions: [0]
21− Property { name: "modelData"; type: "QVariant" }
22 Property { name: "busName"; type: "QByteArray" }
21 Property { name: "busName"; type: "QByteArray" }
23 Property { name: "actions"; type: "QVariantMap" }
22 Property { name: "actions"; type: "QVariantMap" }
24 Property { name: "menuObjectPath"; type: "QByteArray" }
23 Property { name: "menuObjectPath"; type: "QByteArray" }
25 Property { name: "actionStateParser"; type: "ActionStateParser"; isPointer: true }
24 Property { name: "actionStateParser"; type: "ActionStateParser"; isPointer: true }
26 Property { name: "nameOwner"; type: "string"; isReadonly: true }
25 Property { name: "nameOwner"; type: "string"; isReadonly: true }
26+ Property { name: "modelData"; type: "QVariant" }
27 Method {
27 Method {
28 name: "insertRow"
28 name: "insertRow"
29 Parameter { name: "row"; type: "int" }
29 Parameter { name: "row"; type: "int" }
tests/mocks/QMenuModel/unitymenumodel.cpp+1−2
@@ -50,13 +50,12 @@ void UnityMenuModel::setModelData(const QVariant& data)
50{
50{
51 beginResetModel();
51 beginResetModel();
52
52
53− m_modelData.clear();
54 m_modelData = data.toList();
53 m_modelData = data.toList();
54+ Q_EMIT modelDataChanged();
55
55
56 endResetModel();
56 endResetModel();
57}
57}
58
58
59−
60void UnityMenuModel::insertRow(int row, const QVariant& data)
59void UnityMenuModel::insertRow(int row, const QVariant& data)
61{
60{
62 row = qMin(row, rowCount());
61 row = qMin(row, rowCount());
tests/mocks/QMenuModel/unitymenumodel.h+6−2
@@ -27,13 +27,15 @@ class ActionStateParser;
27class Q_DECL_EXPORT UnityMenuModel : public QAbstractListModel
27class Q_DECL_EXPORT UnityMenuModel : public QAbstractListModel
28{
28{
29 Q_OBJECT
29 Q_OBJECT
30− Q_PROPERTY(QVariant modelData READ modelData WRITE setModelData NOTIFY modelDataChanged)
31 Q_PROPERTY(QByteArray busName READ busName WRITE setBusName NOTIFY busNameChanged)
30 Q_PROPERTY(QByteArray busName READ busName WRITE setBusName NOTIFY busNameChanged)
32 Q_PROPERTY(QVariantMap actions READ actions WRITE setActions NOTIFY actionsChanged)
31 Q_PROPERTY(QVariantMap actions READ actions WRITE setActions NOTIFY actionsChanged)
33 Q_PROPERTY(QByteArray menuObjectPath READ menuObjectPath WRITE setMenuObjectPath NOTIFY menuObjectPathChanged)
32 Q_PROPERTY(QByteArray menuObjectPath READ menuObjectPath WRITE setMenuObjectPath NOTIFY menuObjectPathChanged)
34 Q_PROPERTY(ActionStateParser* actionStateParser READ actionStateParser WRITE setActionStateParser NOTIFY actionStateParserChanged)
33 Q_PROPERTY(ActionStateParser* actionStateParser READ actionStateParser WRITE setActionStateParser NOTIFY actionStateParserChanged)
35 Q_PROPERTY(QString nameOwner READ nameOwner NOTIFY nameOwnerChanged)
34 Q_PROPERTY(QString nameOwner READ nameOwner NOTIFY nameOwnerChanged)
36
35
36+ // internal mock properties
37+ Q_PROPERTY(QVariant modelData READ modelData WRITE setModelData NOTIFY modelDataChanged)
38+
37public:
39public:
38 UnityMenuModel(QObject *parent = nullptr);
40 UnityMenuModel(QObject *parent = nullptr);
39 virtual ~UnityMenuModel();
41 virtual ~UnityMenuModel();
@@ -81,9 +83,11 @@ Q_SIGNALS:
81 void actionsChanged();
83 void actionsChanged();
82 void menuObjectPathChanged();
84 void menuObjectPathChanged();
83 void actionStateParserChanged();
85 void actionStateParserChanged();
84− void modelDataChanged();
85 void nameOwnerChanged();
86 void nameOwnerChanged();
86
87
88+ // Internal mock usage
89+ void modelDataChanged();
90+
87private:
91private:
88 QVariantMap rowData(int row) const;
92 QVariantMap rowData(int row) const;
89 QVariant subMenuData(int row) const;
93 QVariant subMenuData(int row) const;
tests/mocks/Ubuntu/Payments/Payments.qmltypes+2
@@ -37,6 +37,8 @@ Module {
37 Parameter { name: "error"; type: "string" }
37 Parameter { name: "error"; type: "string" }
38 }
38 }
39 Signal { name: "purchaseCompleted" }
39 Signal { name: "purchaseCompleted" }
40+ Signal { name: "purchaseCancelled" }
40 Method { name: "start" }
41 Method { name: "start" }
42+ Method { name: "process" }
41 }
43 }
42}
44}
tests/mocks/Ubuntu/Telephony/Telephony.qmltypes+2−1
@@ -22,7 +22,8 @@ Module {
22 exportMetaObjectRevisions: [0]
22 exportMetaObjectRevisions: [0]
23 Property { name: "phoneNumber"; type: "string" }
23 Property { name: "phoneNumber"; type: "string" }
24 Property { name: "isConference"; type: "bool" }
24 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" }
26 }
27 }
27 Component {
28 Component {
28 name: "MockCallManager"
29 name: "MockCallManager"
tests/mocks/Unity/Application/Application.qmltypes+13
@@ -238,6 +238,7 @@ Module {
238 Property { name: "state"; type: "State"; isReadonly: true }
238 Property { name: "state"; type: "State"; isReadonly: true }
239 Property { name: "name"; type: "string"; isReadonly: true }
239 Property { name: "name"; type: "string"; isReadonly: true }
240 Property { name: "live"; type: "bool"; isReadonly: true }
240 Property { name: "live"; type: "bool"; isReadonly: true }
241+ Property { name: "orientation"; type: "Qt::ScreenOrientation" }
241 Signal {
242 Signal {
242 name: "typeChanged"
243 name: "typeChanged"
243 Parameter { type: "Type" }
244 Parameter { type: "Type" }
@@ -268,9 +269,14 @@ Module {
268 exportMetaObjectRevisions: [0]
269 exportMetaObjectRevisions: [0]
269 Property { name: "name"; type: "string"; isReadonly: true }
270 Property { name: "name"; type: "string"; isReadonly: true }
270 Property { name: "surface"; type: "MirSurfaceItem"; isReadonly: true; isPointer: true }
271 Property { name: "surface"; type: "MirSurfaceItem"; isReadonly: true; isPointer: true }
272+ Property { name: "application"; type: "ApplicationInfo"; isReadonly: true; isPointer: true }
271 Property { name: "parentSession"; type: "Session"; isReadonly: true; isPointer: true }
273 Property { name: "parentSession"; type: "Session"; isReadonly: true; isPointer: true }
272 Property { name: "childSessions"; type: "SessionModel"; isReadonly: true; isPointer: true }
274 Property { name: "childSessions"; type: "SessionModel"; isReadonly: true; isPointer: true }
273 Property { name: "live"; type: "bool"; isReadonly: true }
275 Property { name: "live"; type: "bool"; isReadonly: true }
276+ Signal {
277+ name: "applicationChanged"
278+ Parameter { type: "ApplicationInfo"; isPointer: true }
279+ }
274 Signal {
280 Signal {
275 name: "surfaceChanged"
281 name: "surfaceChanged"
276 Parameter { type: "MirSurfaceItem"; isPointer: true }
282 Parameter { type: "MirSurfaceItem"; isPointer: true }
@@ -368,6 +374,12 @@ Module {
368 Property { name: "stage"; type: "Stage"; isReadonly: true }
374 Property { name: "stage"; type: "Stage"; isReadonly: true }
369 Property { name: "state"; type: "State"; isReadonly: true }
375 Property { name: "state"; type: "State"; isReadonly: true }
370 Property { name: "focused"; type: "bool"; isReadonly: true }
376 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 }
371 Signal {
383 Signal {
372 name: "nameChanged"
384 name: "nameChanged"
373 Parameter { name: "name"; type: "string" }
385 Parameter { name: "name"; type: "string" }
@@ -414,6 +426,7 @@ Module {
414 Property { name: "count"; type: "int"; isReadonly: true }
426 Property { name: "count"; type: "int"; isReadonly: true }
415 Property { name: "focusedApplicationId"; type: "string"; isReadonly: true }
427 Property { name: "focusedApplicationId"; type: "string"; isReadonly: true }
416 Property { name: "suspended"; type: "bool" }
428 Property { name: "suspended"; type: "bool" }
429+ Property { name: "forceDashActive"; type: "bool" }
417 Signal {
430 Signal {
418 name: "focusRequested"
431 name: "focusRequested"
419 Parameter { name: "appId"; type: "string" }
432 Parameter { name: "appId"; type: "string" }
tests/mocks/Unity/DashCommunicator/DashCommunicator.qmltypes+2−2
@@ -34,13 +34,13 @@ Module {
34 name: "setCurrentScopeRequested"
34 name: "setCurrentScopeRequested"
35 Parameter { name: "scopeId"; type: "string" }
35 Parameter { name: "scopeId"; type: "string" }
36 Parameter { name: "animate"; type: "bool" }
36 Parameter { name: "animate"; type: "bool" }
37− Parameter { name: "reset"; type: "bool" }
37+ Parameter { name: "isSwipe"; type: "bool" }
38 }
38 }
39 Method {
39 Method {
40 name: "mockSetCurrentScope"
40 name: "mockSetCurrentScope"
41 Parameter { name: "scopeId"; type: "string" }
41 Parameter { name: "scopeId"; type: "string" }
42 Parameter { name: "animate"; type: "bool" }
42 Parameter { name: "animate"; type: "bool" }
43− Parameter { name: "reset"; type: "bool" }
43+ Parameter { name: "isSwipe"; type: "bool" }
44 }
44 }
45 }
45 }
46}
46}
tests/mocks/Unity/Indicators/CMakeLists.txt+3−10
@@ -12,24 +12,17 @@ include_directories(
12
12
13set(IndicatorsFakeQml_SOURCES
13set(IndicatorsFakeQml_SOURCES
14 fakeplugin.cpp
14 fakeplugin.cpp
15+ fakeindicatorsmodel.cpp
16+ fakeunitymenumodelcache.cpp
15 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/indicators.h
17 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/indicators.h
16 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/menucontentactivator.cpp
18 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/menucontentactivator.cpp
19+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/sharedunitymenumodel.cpp
17 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/unitymenumodelcache.cpp
20 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/unitymenumodelcache.cpp
18 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/unitymenumodelstack.cpp
21 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/unitymenumodelstack.cpp
19 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/visibleindicatorsmodel.cpp
22 ${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}
29)
23)
30
24
31add_library(IndicatorsFakeQml SHARED
25add_library(IndicatorsFakeQml SHARED
32− ${IndicatorsFakeQml_RESOURCES_RCC}
33 ${IndicatorsFakeQml_SOURCES}
26 ${IndicatorsFakeQml_SOURCES}
34)
27)
35add_definitions(-DUNITYINDICATORS_LIBRARY)
28add_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 {
29 exports: ["Unity.Indicators/FakeIndicatorsModel 0.1"]
29 exports: ["Unity.Indicators/FakeIndicatorsModel 0.1"]
30 exportMetaObjectRevisions: [0]
30 exportMetaObjectRevisions: [0]
31 Property { name: "count"; type: "int"; isReadonly: true }
31 Property { name: "count"; type: "int"; isReadonly: true }
32+ Property { name: "modelData"; type: "QVariant" }
32 Method {
33 Method {
33 name: "load"
34 name: "load"
34 Parameter { name: "profile"; type: "string" }
35 Parameter { name: "profile"; type: "string" }
@@ -38,6 +39,15 @@ Module {
38 name: "append"
39 name: "append"
39 Parameter { name: "row"; type: "QVariantMap" }
40 Parameter { name: "row"; type: "QVariantMap" }
40 }
41 }
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+ }
41 Method {
51 Method {
42 name: "data"
52 name: "data"
43 type: "QVariant"
53 type: "QVariant"
@@ -45,6 +55,27 @@ Module {
45 Parameter { name: "role"; type: "int" }
55 Parameter { name: "role"; type: "int" }
46 }
56 }
47 }
57 }
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+ }
48 Component {
79 Component {
49 name: "FlatMenuProxyModelRole"
80 name: "FlatMenuProxyModelRole"
50 prototype: "QObject"
81 prototype: "QObject"
@@ -160,19 +191,18 @@ Module {
160 }
191 }
161 Component { name: "QIdentityProxyModel"; prototype: "QAbstractProxyModel" }
192 Component { name: "QIdentityProxyModel"; prototype: "QAbstractProxyModel" }
162 Component {
193 Component {
163− name: "UnityMenuModelCache"
194+ name: "SharedUnityMenuModel"
164 prototype: "QObject"
195 prototype: "QObject"
165− exports: ["Unity.Indicators/UnityMenuModelCache 0.1"]
196+ exports: ["Unity.Indicators/SharedUnityMenuModel 0.1"]
166− isCreatable: false
167− isSingleton: true
168 exportMetaObjectRevisions: [0]
197 exportMetaObjectRevisions: [0]
169− Method {
198+ Property { name: "busName"; type: "QByteArray" }
170− name: "model"
199+ Property { name: "menuObjectPath"; type: "QByteArray" }
200+ Property { name: "actions"; type: "QVariantMap" }
171− type: "UnityMenuModel*"
201+ Property { name: "model"; type: "UnityMenuModel"; isReadonly: true; isPointer: true }
172− Parameter { name: "bus"; type: "QByteArray" }
202+ }
173− Parameter { name: "path"; type: "QByteArray" }
203+ Component {
174− Parameter { name: "actions"; type: "QVariantMap" }
204+ name: "UnityMenuModelCache"
175− }
205+ prototype: "QObject"
176 Method {
206 Method {
177 name: "contains"
207 name: "contains"
178 type: "bool"
208 type: "bool"
tests/mocks/Unity/Indicators/IndicatorsModel.qml+143−35
@@ -18,43 +18,151 @@ import QtQuick 2.0
18import Unity.Indicators 0.1 as Indicators
18import Unity.Indicators 0.1 as Indicators
19
19
20Indicators.FakeIndicatorsModel {
20Indicators.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+ ]
21
163
22 function load(profile) {
164 function load(profile) {
23 unload();
165 unload();
24−
166+ root.modelData = originalModelData;
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− });
59 }
167 }
60}
168}
tests/mocks/Unity/Indicators/RootActionState.qml+17−9
@@ -19,15 +19,23 @@
19
19
20import QtQuick 2.0
20import QtQuick 2.0
21
21
22−QtObject {
22+Item {
23− property var menu
23+ property var menu: null
24− property bool valid: false
24+ property bool valid: cachedState !== undefined
25− property string title
25+ property string title: cachedState && cachedState.hasOwnProperty("title") ? cachedState["title"] : ""
26− property string leftLabel
26+ property string leftLabel: cachedState && cachedState.hasOwnProperty("pre-label") ? cachedState["pre-label"] : ""
27− property string rightLabel
27+ property string rightLabel: cachedState && cachedState.hasOwnProperty("label") ? cachedState["label"] : ""
28− property var icons
28+ property var icons: cachedState && cachedState.hasOwnProperty("icons") ? cachedState["icons"] : []
29− property string accessibleName
29+ property string accessibleName: cachedState && cachedState.hasOwnProperty("accessible-desc") ? cachedState["accessible-desc"] : ""
30− property bool visible: true
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+ }
31
39
32 signal updated
40 signal updated
33
41
tests/mocks/Unity/Indicators/fakeindicatorsmodel.cpp+50−19
@@ -31,7 +31,6 @@ FakeIndicatorsModel::FakeIndicatorsModel(QObject *parent)
31/*! \internal */
31/*! \internal */
32FakeIndicatorsModel::~FakeIndicatorsModel()
32FakeIndicatorsModel::~FakeIndicatorsModel()
33{
33{
34− qDeleteAll(m_indicators);
35}
34}
36
35
37int FakeIndicatorsModel::count() const
36int FakeIndicatorsModel::count() const
@@ -47,31 +46,63 @@ void FakeIndicatorsModel::unload()
47{
46{
48 beginResetModel();
47 beginResetModel();
49
48
50− qDeleteAll(m_indicators);
49+ m_modelData.clear();
51− m_indicators.clear();
50+ Q_EMIT modelDataChanged();
52
51
53 endResetModel();
52 endResetModel();
54}
53}
55
54
56
55
57−void FakeIndicatorsModel::append(const QVariantMap& row)
56+void FakeIndicatorsModel::append(const QVariantMap& data)
58{
57{
59− Indicator* new_row = new QHash<int, QVariant>();
58+ QList<QVariant> allData = m_modelData.toList();
60− for (auto iter = row.begin(); iter != row.end(); ++iter )
59+ beginInsertRows(QModelIndex(), allData.count(), allData.count());
61− {
60+
62− int key = roleNames().key(iter.key().toUtf8(), -1);
61+ allData.append(data);
63− if (key != -1) {
62+ m_modelData = allData;
64− new_row->insert(key, iter.value());
63+ Q_EMIT modelDataChanged();
65− }
66− }
67
64
68− beginInsertRows(QModelIndex(), m_indicators.count(), m_indicators.count());
65+ endInsertRows();
66+}
69
67
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();
71
78
72 endInsertRows();
79 endInsertRows();
73}
80}
74
81
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+
75QHash<int, QByteArray> FakeIndicatorsModel::roleNames() const
106QHash<int, QByteArray> FakeIndicatorsModel::roleNames() const
76{
107{
77 static QHash<int, QByteArray> roles;
108 static QHash<int, QByteArray> roles;
@@ -91,18 +122,18 @@ int FakeIndicatorsModel::columnCount(const QModelIndex &) const
91 return 1;
122 return 1;
92}
123}
93
124
94−Q_INVOKABLE QVariant FakeIndicatorsModel::data(int row, int role) const
125+QVariant FakeIndicatorsModel::data(int row, int role) const
95{
126{
96 return data(index(row, 0), role);
127 return data(index(row, 0), role);
97}
128}
98
129
99QVariant FakeIndicatorsModel::data(const QModelIndex &index, int role) const
130QVariant FakeIndicatorsModel::data(const QModelIndex &index, int role) const
100{
131{
132+ QList<QVariant> dataList = m_modelData.toList();
101− if (!index.isValid() || index.row() >= m_indicators.size())
133+ if (!index.isValid() || index.row() >= dataList.size())
102 return QVariant();
134 return QVariant();
103
135
104− Indicator* indicator = m_indicators[index.row()];
136+ return dataList[index.row()].toMap()[roleNames()[role]];
105− return indicator->value(role, QVariant());
106}
137}
107
138
108QModelIndex FakeIndicatorsModel::parent(const QModelIndex&) const
139QModelIndex FakeIndicatorsModel::parent(const QModelIndex&) const
@@ -112,5 +143,5 @@ QModelIndex FakeIndicatorsModel::parent(const QModelIndex&) const
112
143
113int FakeIndicatorsModel::rowCount(const QModelIndex&) const
144int FakeIndicatorsModel::rowCount(const QModelIndex&) const
114{
145{
115− return m_indicators.count();
146+ return m_modelData.toList().count();
116}
147}
tests/mocks/Unity/Indicators/fakeindicatorsmodel.h+8−2
@@ -27,6 +27,7 @@ class FakeIndicatorsModel : public QAbstractListModel
27 Q_OBJECT
27 Q_OBJECT
28 Q_ENUMS(Roles)
28 Q_ENUMS(Roles)
29 Q_PROPERTY(int count READ count NOTIFY countChanged)
29 Q_PROPERTY(int count READ count NOTIFY countChanged)
30+ Q_PROPERTY(QVariant modelData READ modelData WRITE setModelData NOTIFY modelDataChanged)
30public:
31public:
31
32
32 FakeIndicatorsModel(QObject *parent=0);
33 FakeIndicatorsModel(QObject *parent=0);
@@ -36,9 +37,14 @@ public:
36 Q_INVOKABLE void unload();
37 Q_INVOKABLE void unload();
37
38
38 Q_INVOKABLE void append(const QVariantMap& row);
39 Q_INVOKABLE void append(const QVariantMap& row);
40+ Q_INVOKABLE void insert(int row, const QVariantMap& data);
41+ Q_INVOKABLE void remove(int row);
39
42
40 Q_INVOKABLE QVariant data(int row, int role) const;
43 Q_INVOKABLE QVariant data(int row, int role) const;
41
44
45+ void setModelData(const QVariant& data);
46+ QVariant modelData() const { return m_modelData; }
47+
42 /* QAbstractItemModel */
48 /* QAbstractItemModel */
43 QHash<int, QByteArray> roleNames() const;
49 QHash<int, QByteArray> roleNames() const;
44 int columnCount(const QModelIndex &parent = QModelIndex()) const;
50 int columnCount(const QModelIndex &parent = QModelIndex()) const;
@@ -48,12 +54,12 @@ public:
48
54
49Q_SIGNALS:
55Q_SIGNALS:
50 void countChanged();
56 void countChanged();
57+ void modelDataChanged();
51
58
52private:
59private:
53 int count() const;
60 int count() const;
54
61
55− typedef QHash<int, QVariant> Indicator;
62+ QVariant m_modelData;
56− QList<Indicator*> m_indicators;
57};
63};
58
64
59#endif // FAKE_INDICATORSMODEL_H
65#endif // FAKE_INDICATORSMODEL_H
tests/mocks/Unity/Indicators/fakeplugin.cpp+8−4
@@ -26,19 +26,22 @@
26#include "fakeindicatorsmodel.h"
26#include "fakeindicatorsmodel.h"
27#include "indicators.h"
27#include "indicators.h"
28#include "menucontentactivator.h"
28#include "menucontentactivator.h"
29−#include "unitymenumodelcache.h"
29+#include "sharedunitymenumodel.h"
30+#include "fakeunitymenumodelcache.h"
30#include "unitymenumodelstack.h"
31#include "unitymenumodelstack.h"
31#include "visibleindicatorsmodel.h"
32#include "visibleindicatorsmodel.h"
32
33
34+#include <unitymenumodel.h>
35+
33static QObject* menuModelCacheSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
36static QObject* menuModelCacheSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
34 Q_UNUSED(engine);
37 Q_UNUSED(engine);
35 Q_UNUSED(scriptEngine);
38 Q_UNUSED(scriptEngine);
36− return new UnityMenuModelCache;
39+ return FakeUnityMenuModelCache::singleton();
37}
40}
38
41
39void IndicatorsFakePlugin::registerTypes(const char * uri)
42void IndicatorsFakePlugin::registerTypes(const char * uri)
40{
43{
41− Q_INIT_RESOURCE(indicators_fake);
44+ qRegisterMetaType<UnityMenuModel*>("UnityMenuModel*");
42
45
43 // internal
46 // internal
44 qmlRegisterType<FakeIndicatorsModel>(uri, 0, 1, "FakeIndicatorsModel");
47 qmlRegisterType<FakeIndicatorsModel>(uri, 0, 1, "FakeIndicatorsModel");
@@ -47,8 +50,9 @@ void IndicatorsFakePlugin::registerTypes(const char * uri)
47 qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
50 qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
48 qmlRegisterType<UnityMenuModelStack>(uri, 0, 1, "UnityMenuModelStack");
51 qmlRegisterType<UnityMenuModelStack>(uri, 0, 1, "UnityMenuModelStack");
49 qmlRegisterType<VisibleIndicatorsModel>(uri, 0, 1, "VisibleIndicatorsModel");
52 qmlRegisterType<VisibleIndicatorsModel>(uri, 0, 1, "VisibleIndicatorsModel");
53+ qmlRegisterType<SharedUnityMenuModel>(uri, 0, 1, "SharedUnityMenuModel");
50
54
51− qmlRegisterSingletonType<UnityMenuModelCache>(uri, 0, 1, "UnityMenuModelCache", menuModelCacheSingleton);
55+ qmlRegisterSingletonType<FakeUnityMenuModelCache>(uri, 0, 1, "UnityMenuModelCache", menuModelCacheSingleton);
52
56
53 // external uncreatables
57 // external uncreatables
54 qmlRegisterUncreatableType<MenuContentState>(uri, 0, 1, "MenuContentState", "Can't create MenuContentState class");
58 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
3typeinfo Indicators.qmltypes
3typeinfo Indicators.qmltypes
4
4
5IndicatorsModel 0.1 IndicatorsModel.qml
5IndicatorsModel 0.1 IndicatorsModel.qml
6−FakeMenuPage 0.1 FakeMenuPage.qml
7RootActionState 0.1 RootActionState.qml
6RootActionState 0.1 RootActionState.qml
tests/mocks/Unity/Launcher/Launcher.qmltypes+13
@@ -85,6 +85,7 @@ Module {
85 Property { name: "recent"; type: "bool"; isReadonly: true }
85 Property { name: "recent"; type: "bool"; isReadonly: true }
86 Property { name: "progress"; type: "int"; isReadonly: true }
86 Property { name: "progress"; type: "int"; isReadonly: true }
87 Property { name: "count"; type: "int"; isReadonly: true }
87 Property { name: "count"; type: "int"; isReadonly: true }
88+ Property { name: "countVisible"; type: "bool"; isReadonly: true }
88 Property { name: "focused"; type: "bool"; isReadonly: true }
89 Property { name: "focused"; type: "bool"; isReadonly: true }
89 Property {
90 Property {
90 name: "quickList"
91 name: "quickList"
@@ -92,6 +93,14 @@ Module {
92 isReadonly: true
93 isReadonly: true
93 isPointer: true
94 isPointer: true
94 }
95 }
96+ Signal {
97+ name: "nameChanged"
98+ Parameter { name: "name"; type: "string" }
99+ }
100+ Signal {
101+ name: "iconChanged"
102+ Parameter { name: "icon"; type: "string" }
103+ }
95 Signal {
104 Signal {
96 name: "pinnedChanged"
105 name: "pinnedChanged"
97 Parameter { name: "pinned"; type: "bool" }
106 Parameter { name: "pinned"; type: "bool" }
@@ -112,6 +121,10 @@ Module {
112 name: "countChanged"
121 name: "countChanged"
113 Parameter { name: "count"; type: "int" }
122 Parameter { name: "count"; type: "int" }
114 }
123 }
124+ Signal {
125+ name: "countVisibleChanged"
126+ Parameter { name: "countVisible"; type: "bool" }
127+ }
115 Signal {
128 Signal {
116 name: "focusedChanged"
129 name: "focusedChanged"
117 Parameter { name: "focused"; type: "bool" }
130 Parameter { name: "focused"; type: "bool" }
tests/mocks/Unity/Unity.qmltypes+32
@@ -30,6 +30,25 @@ Module {
30 Parameter { name: "row"; type: "int" }
30 Parameter { name: "row"; type: "int" }
31 Parameter { name: "role"; type: "int" }
31 Parameter { name: "role"; type: "int" }
32 }
32 }
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+ }
33 }
52 }
34 Component {
53 Component {
35 name: "PreviewModel"
54 name: "PreviewModel"
@@ -66,6 +85,10 @@ Module {
66 exports: ["Unity/FakeResultsModel 0.2", "Unity/ResultsModel 0.2"]
85 exports: ["Unity/FakeResultsModel 0.2", "Unity/ResultsModel 0.2"]
67 isCreatable: false
86 isCreatable: false
68 exportMetaObjectRevisions: [0, 0]
87 exportMetaObjectRevisions: [0, 0]
88+ Method {
89+ name: "setResultCount"
90+ Parameter { name: "result_count"; type: "int" }
91+ }
69 }
92 }
70 Component {
93 Component {
71 name: "Scope"
94 name: "Scope"
@@ -76,6 +99,15 @@ Module {
76 name: "performQuery"
99 name: "performQuery"
77 Parameter { name: "query"; type: "string" }
100 Parameter { name: "query"; type: "string" }
78 }
101 }
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+ }
79 Method {
111 Method {
80 name: "setSearchInProgress"
112 name: "setSearchInProgress"
81 Parameter { name: "inProg"; type: "bool" }
113 Parameter { name: "inProg"; type: "bool" }
tests/plugins/Unity/Indicators/CMakeLists.txt+1
@@ -40,3 +40,4 @@ indicator_test(indicatorsmodeltest ADDITIONAL_LIBS IndicatorsQml)
40indicator_test(menucontentactivatortest ADDITIONAL_CPPS ${INDICATORS_DIR}/menucontentactivator.cpp)
40indicator_test(menucontentactivatortest ADDITIONAL_CPPS ${INDICATORS_DIR}/menucontentactivator.cpp)
41indicator_test(unitymenumodelstacktest ADDITIONAL_CPPS ${TEST_DIR}/mocks/QMenuModel/unitymenumodel.cpp ${INDICATORS_DIR}/unitymenumodelstack.cpp)
41indicator_test(unitymenumodelstacktest ADDITIONAL_CPPS ${TEST_DIR}/mocks/QMenuModel/unitymenumodel.cpp ${INDICATORS_DIR}/unitymenumodelstack.cpp)
42indicator_test(rootactionstatetest ADDITIONAL_LIBS IndicatorsQml)
42indicator_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)
19set(qmltest_DEFAULT_NO_ADD_TEST TRUE)
19set(qmltest_DEFAULT_NO_ADD_TEST TRUE)
20set(qmltest_DEFAULT_PROPERTIES ENVIRONMENT "LC_ALL=C")
20set(qmltest_DEFAULT_PROPERTIES ENVIRONMENT "LC_ALL=C")
21
21
22−add_qml_test(. Shell ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
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")
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")
24+add_qml_test(. TabletShell ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full:${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
25add_qml_test(Components Background)
25add_qml_test(Components Background)
26add_qml_test(Components Carousel)
26add_qml_test(Components Carousel)
27add_qml_test(Components DraggingArea)
27add_qml_test(Components DraggingArea)
@@ -72,14 +72,13 @@ add_qml_test(Launcher Launcher)
72add_qml_test(Notifications Notifications)
72add_qml_test(Notifications Notifications)
73add_qml_test(Notifications VisualSnapDecisionsQueue)
73add_qml_test(Notifications VisualSnapDecisionsQueue)
74add_qml_test(Panel ActiveCallHint)
74add_qml_test(Panel ActiveCallHint)
75−add_qml_test(Panel IndicatorRow)
75+add_qml_test(Panel IndicatorRow ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
76−add_qml_test(Panel Indicators)
76+add_qml_test(Panel Indicators ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
77−add_qml_test(Panel MenuContent)
77+add_qml_test(Panel MenuContent ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
78−add_qml_test(Panel Panel)
78+add_qml_test(Panel Panel ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
79add_qml_test(Panel SearchIndicator)
79add_qml_test(Panel SearchIndicator)
80add_qml_test(Panel/Indicators DefaultIndicatorWidget ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
80add_qml_test(Panel/Indicators DefaultIndicatorWidget ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
81add_qml_test(Panel/Indicators DefaultIndicatorPage ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
81add_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")
83# These MenuItemFactory tests need the test/mocks/ to come before plugins/
82# These MenuItemFactory tests need the test/mocks/ to come before plugins/
84add_qml_test(Panel/Indicators MenuItemFactory IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks ${qmltest_DEFAULT_IMPORT_PATHS})
83add_qml_test(Panel/Indicators MenuItemFactory IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks ${qmltest_DEFAULT_IMPORT_PATHS})
85add_qml_test(Panel/Indicators MessageMenuItemFactory IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks ${qmltest_DEFAULT_IMPORT_PATHS})
84add_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
19import ".."
19import ".."
20import "../../../qml/Greeter"
20import "../../../qml/Greeter"
21import Ubuntu.Components 0.1
21import Ubuntu.Components 0.1
22−import QMenuModel 0.1
22+import Unity.Indicators 0.1 as Indicators
23import Unity.Test 0.1 as UT
23import Unity.Test 0.1 as UT
24
24
25Rectangle {
25Rectangle {
@@ -36,56 +36,73 @@ Rectangle {
36 }
36 }
37 }
37 }
38
38
39− UnityMenuModel {
39+ function updateDatetimeModelTime(label) {
40− id: menuModel
40+ Indicators.UnityMenuModelCache.setCachedModelData("com.canonical.indicator.datetime",
41− modelData: [{
41+ "/com/canonical/indicator/datetime/phone",
42+ "/com/canonical/indicator/datetime",
43+ [{
42− "rowData": {
44+ "rowData": {
43− "actionState": { "label": Qt.formatTime(new Date("October 13, 1975 11:13:00")) }
45+ "actionState": { "label": label }
44− }
46+ }
45− }]
47+ }]);
46 }
48 }
47
49
48 UT.UnityTestCase {
50 UT.UnityTestCase {
49 name: "Clock"
51 name: "Clock"
52+ when: windowShown
50
53
51 function init() {
54 function init() {
52− var cachedModel = findChild(clock, "timeModel");
55+ updateDatetimeModelTime(Qt.formatTime(new Date("October 13, 1975 12:14:00")));
53− verify(cachedModel !== undefined);
56+ clock.visible = true;
54− cachedModel.model = menuModel;
55 }
57 }
56
58
57− function test_customDate() {
59+ // Test that the date portion of the clock updates with custom value.
58− var dateObj = new Date("October 13, 1975 11:13:00")
60+ // Time portion is controlled by indicators
59− var dateString = Qt.formatDate(dateObj, Qt.DefaultLocaleLongDate)
61+ function test_updateDate() {
60− var timeString = Qt.formatTime(dateObj)
62+ var dateLabel = findChild(clock, "dateLabel");
63+ var timeLabel = findChild(clock, "timeLabel");
61
64
62− clock.currentDate = dateObj
65+ var timeString = Qt.formatTime(new Date("October 13, 1975 12:14:00"));
63− var dateLabel = findChild(clock, "dateLabel")
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+
64− compare(dateLabel.text, dateString, "Not the expected date")
72+ compare(dateLabel.text, dateString, "Not the expected date");
65− var timeLabel = findChild(clock, "timeLabel")
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+
66− compare(timeLabel.text, timeString, "Not the expected time")
80+ compare(dateLabel.text, dateString2, "Not the expected date");
81+ compare(timeLabel.text,timeString, "Time should come from indicators");
67 }
82 }
68
83
69− function test_dateUpdate() {
84+ // Test that the date portion of the clock updates with custom value.
70− var dateObj = new Date("October 13, 1975 11:13:00")
85+ // Time portion is controlled by indicators
71− var dateString = Qt.formatDate(dateObj, Qt.DefaultLocaleLongDate)
86+ function test_updateTime() {
72− var timeString = Qt.formatTime(dateObj)
87+ var timeLabel = findChild(clock, "timeLabel");
73
88
74− clock.visible = false
89+ var timeString1 = Qt.formatTime(new Date("October 13, 1975 11:15:00"));
75− var timeModel = findInvisibleChild(clock, "timeModel")
90+ var timeString2 = Qt.formatTime(new Date("October 14, 1976 12:16:00"));
76
91
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");
78
94
79− clock.currentDate = dateObj
95+ updateDatetimeModelTime(timeString2);
96+ compare(timeLabel.text, timeString2, "Time should come from indicators");
97+ }
80
98
81− var dateLabel = findChild(clock, "dateLabel")
99+ function test_indicatorDisconnect() {
82− compare(dateLabel.text, dateString, "Not the expected date")
100+ clock.visible = false
83− var timeLabel = findChild(clock, "timeLabel")
101+ var timeModel = findInvisibleChild(clock, "timeModel")
84− compare(timeLabel.text, timeString, "Not the expected time")
102+ compare(timeModel.menuObjectPath, "", "Clock shouldn't be connected to Indicators when not visible.")
85
103
86 clock.visible = true
104 clock.visible = true
87−
88− verify(timeModel.menuObjectPath != "", "Should be connected to Indicators.")
105+ verify(timeModel.menuObjectPath !== "", "Should be connected to Indicators.")
89 }
106 }
90 }
107 }
91}
108}
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 @@
17import QtQuick 2.0
17import QtQuick 2.0
18import QtTest 1.0
18import QtTest 1.0
19import Unity.Test 0.1 as UT
19import Unity.Test 0.1 as UT
20−import QMenuModel 0.1
20+import Unity.Indicators 0.1 as Indicators
21import "../../../../qml/Panel/Indicators"
21import "../../../../qml/Panel/Indicators"
22
22
23Item {
23Item {
@@ -25,18 +25,14 @@ Item {
25 width: units.gu(40)
25 width: units.gu(40)
26 height: units.gu(70)
26 height: units.gu(70)
27
27
28− DefaultIndicatorPage {
28+ DefaultIndicatorPage {
29 id: page
29 id: page
30−
31 anchors.fill: parent
30 anchors.fill: parent
32
31
33− menuModel: UnityMenuModel {}
34− busName: "test"
35− actionsObjectPath: "test"
36− menuObjectPath: "test"
37−
38 identifier: "test-indicator"
32 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"
40 }
36 }
41
37
42 property var fullMenuData: [{
38 property var fullMenuData: [{
@@ -113,29 +109,30 @@ Item {
113 "submenu": []
109 "submenu": []
114 }]; // end row 1
110 }]; // end row 1
115
111
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+
116 UT.UnityTestCase {
119 UT.UnityTestCase {
117 name: "DefaultIndicatorPage"
120 name: "DefaultIndicatorPage"
118
121
119 function init() {
122 function init() {
120− var mainMenu = findChild(page, "mainMenu");
123+ initializeMenuData([]);
121− page.menuModel.modelData = [];
122− verify(mainMenu.model !== null);
123 }
124 }
124
125
125 function test_reloadData() {
126 function test_reloadData() {
126 var mainMenu = findChild(page, "mainMenu");
127 var mainMenu = findChild(page, "mainMenu");
127
128
128− page.menuModel.modelData = [];
129 tryCompare(mainMenu, "count", 0);
129 tryCompare(mainMenu, "count", 0);
130
130
131− page.menuModel.modelData = fullMenuData;
131+ initializeMenuData(fullMenuData);
132 tryCompare(mainMenu, "count", 3);
132 tryCompare(mainMenu, "count", 3);
133
133
134− page.menuModel.modelData = [];
134+ initializeMenuData([]);
135 tryCompare(mainMenu, "count", 0);
135 tryCompare(mainMenu, "count", 0);
136−
137− page.menuModel.modelData = fullMenuData;
138− tryCompare(mainMenu, "count", 3);
139 }
136 }
140
137
141 function test_traverse_rootMenuType_data() {
138 function test_traverse_rootMenuType_data() {
@@ -147,7 +144,7 @@ Item {
147
144
148 function test_traverse_rootMenuType(data) {
145 function test_traverse_rootMenuType(data) {
149 page.rootMenuType = data.rootMenuType;
146 page.rootMenuType = data.rootMenuType;
150− page.menuModel.modelData = fullMenuData;
147+ initializeMenuData(fullMenuData);
151
148
152 var mainMenu = findChild(page, "mainMenu");
149 var mainMenu = findChild(page, "mainMenu");
153 tryCompare(mainMenu, "count", data.expectedCount);
150 tryCompare(mainMenu, "count", data.expectedCount);
tests/qmltests/Panel/Indicators/tst_DefaultIndicatorWidget.qml−8
@@ -33,7 +33,6 @@ Item {
33 top: parent.top
33 top: parent.top
34 }
34 }
35
35
36− menuModel: UnityMenuModel {}
37 busName: "test"
36 busName: "test"
38 actionsObjectPath: "test"
37 actionsObjectPath: "test"
39 deviceMenuObjectPath: "test"
38 deviceMenuObjectPath: "test"
@@ -48,13 +47,6 @@ Item {
48 name: "DefaultIndicatorWidget"
47 name: "DefaultIndicatorWidget"
49 when: windowShown
48 when: windowShown
50
49
51− function init() {
52− widget.rootActionState.icons = [];
53− widget.rootActionState.leftLabel = "";
54− widget.rootActionState.rightLabel = "";
55− waitForRendering(widget)
56− }
57−
58 // FIXME: add tests
50 // FIXME: add tests
59 }
51 }
60}
52}
tests/qmltests/Panel/tst_IndicatorItem.qml+1−1
@@ -43,7 +43,7 @@ Rectangle {
43
43
44 function test_empty() {
44 function test_empty() {
45 compare(indicatorItem.indicatorVisible, false, "IndicatorItem should not be visible.");
45 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";
47 tryCompare(indicatorItem, "indicatorVisible", true);
47 tryCompare(indicatorItem, "indicatorVisible", true);
48 }
48 }
49 }
49 }
tests/qmltests/Panel/tst_IndicatorRow.qml+17−19
@@ -30,15 +30,6 @@ Item {
30 width: units.gu(40)
30 width: units.gu(40)
31 height: units.gu(60)
31 height: units.gu(60)
32
32
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−
42 PanelBackground {
33 PanelBackground {
43 anchors.fill: indicatorRow
34 anchors.fill: indicatorRow
44 }
35 }
@@ -63,20 +54,33 @@ Item {
63 name: "IndicatorRow"
54 name: "IndicatorRow"
64 when: windowShown
55 when: windowShown
65
56
57+ function init() {
58+ indicatorModel.load("test1");
59+
60+ indicatorRow.state = "initial";
61+ indicatorRow.setCurrentItemIndex(-1);
62+ indicatorRow.unitProgress = 0.0;
63+ }
64+
66 function get_indicator_item(index) {
65 function get_indicator_item(index) {
67 return findChild(indicatorRow.row, "item" + index);
66 return findChild(indicatorRow.row, "item" + index);
68 }
67 }
69
68
70 function test_set_current_item() {
69 function test_set_current_item() {
71− init_test();
72 indicatorRow.setCurrentItemIndex(0);
70 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");
74
74
75 indicatorRow.setCurrentItemIndex(1);
75 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");
77
79
78 indicatorRow.setCurrentItemIndex(2);
80 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");
80 }
84 }
81
85
82 function test_highlight_data() {
86 function test_highlight_data() {
@@ -93,8 +97,6 @@ Item {
93 }
97 }
94
98
95 function test_highlight(data) {
99 function test_highlight(data) {
96− init_test();
97−
98 indicatorRow.unitProgress = data.progress;
100 indicatorRow.unitProgress = data.progress;
99 indicatorRow.setCurrentItemIndex(data.index);
101 indicatorRow.setCurrentItemIndex(data.index);
100
102
@@ -119,8 +121,6 @@ Item {
119 }
121 }
120
122
121 function test_opacity(data) {
123 function test_opacity(data) {
122− init_test();
123−
124 indicatorRow.unitProgress = data.progress;
124 indicatorRow.unitProgress = data.progress;
125 indicatorRow.setCurrentItemIndex(data.index);
125 indicatorRow.setCurrentItemIndex(data.index);
126
126
@@ -145,8 +145,6 @@ Item {
145 }
145 }
146
146
147 function test_dimmed(data) {
147 function test_dimmed(data) {
148− init_test();
149−
150 indicatorRow.unitProgress = data.progress;
148 indicatorRow.unitProgress = data.progress;
151 indicatorRow.setCurrentItemIndex(data.index);
149 indicatorRow.setCurrentItemIndex(data.index);
152
150
tests/qmltests/Panel/tst_Indicators.qml+1
@@ -158,6 +158,7 @@ Item {
158 function init_invisible_indicator(identifier) {
158 function init_invisible_indicator(identifier) {
159 tryCompareFunction(function() { return findChild(indicators, identifier+"-delegate") !== undefined }, true);
159 tryCompareFunction(function() { return findChild(indicators, identifier+"-delegate") !== undefined }, true);
160 var item = findChild(indicators, identifier+"-delegate");
160 var item = findChild(indicators, identifier+"-delegate");
161+ verify(item !== null);
161
162
162 item.enabled = false;
163 item.enabled = false;
163 }
164 }
tests/qmltests/Panel/tst_MenuContent.qml−8
@@ -26,14 +26,6 @@ Item {
26 width: units.gu(40)
26 width: units.gu(40)
27 height: units.gu(70)
27 height: units.gu(70)
28
28
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−
37 // Dummy objects
29 // Dummy objects
38 Item { id: greeter }
30 Item { id: greeter }
39 Item { id: handle }
31 Item { id: handle }
tests/qmltests/tst_Shell.qml+2
@@ -65,6 +65,8 @@ Row {
65 property bool itemDestroyed: false
65 property bool itemDestroyed: false
66 sourceComponent: Component {
66 sourceComponent: Component {
67 Shell {
67 Shell {
68+ property string indicatorProfile: "phone"
69+
68 Component.onDestruction: {
70 Component.onDestruction: {
69 shellLoader.itemDestroyed = true;
71 shellLoader.itemDestroyed = true;
70 }
72 }
tests/qmltests/tst_ShellWithPin.qml+2
@@ -61,6 +61,8 @@ Item {
61 property bool itemDestroyed: false
61 property bool itemDestroyed: false
62 sourceComponent: Component {
62 sourceComponent: Component {
63 Shell {
63 Shell {
64+ property string indicatorProfile: "phone"
65+
64 Component.onDestruction: {
66 Component.onDestruction: {
65 shellLoader.itemDestroyed = true
67 shellLoader.itemDestroyed = true
66 }
68 }
tests/qmltests/tst_TabletShell.qml+2
@@ -57,6 +57,8 @@ Row {
57 property bool itemDestroyed: false
57 property bool itemDestroyed: false
58 sourceComponent: Component {
58 sourceComponent: Component {
59 Shell {
59 Shell {
60+ property string indicatorProfile: "phone"
61+
60 Component.onDestruction: {
62 Component.onDestruction: {
61 shellLoader.itemDestroyed = true
63 shellLoader.itemDestroyed = true
62 }
64 }