on xenial help sign in
merged with lp:~nick-dedekind/unity8/sharedunitymenumodel
2a3f68aNick Dedekind
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/plugin.cpp+6−1
@@ -30,19 +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
43void Indicators2Plugin::registerTypes(const char *uri)
46void Indicators2Plugin::registerTypes(const char *uri)
44{
47{
45 Q_INIT_RESOURCE(indicators);
48 Q_INIT_RESOURCE(indicators);
49+ qRegisterMetaType<UnityMenuModel*>("UnityMenuModel*");
46
50
47 qmlRegisterType<IndicatorsManager>(uri, 0, 1, "IndicatorsManager");
51 qmlRegisterType<IndicatorsManager>(uri, 0, 1, "IndicatorsManager");
48 qmlRegisterType<IndicatorsModel>(uri, 0, 1, "IndicatorsModel");
52 qmlRegisterType<IndicatorsModel>(uri, 0, 1, "IndicatorsModel");
@@ -51,6 +55,7 @@ void Indicators2Plugin::registerTypes(const char *uri)
51 qmlRegisterType<RootActionState>(uri, 0, 1, "RootActionState");
55 qmlRegisterType<RootActionState>(uri, 0, 1, "RootActionState");
52 qmlRegisterType<ModelPrinter>(uri, 0, 1, "ModelPrinter");
56 qmlRegisterType<ModelPrinter>(uri, 0, 1, "ModelPrinter");
53 qmlRegisterType<VisibleIndicatorsModel>(uri, 0, 1, "VisibleIndicatorsModel");
57 qmlRegisterType<VisibleIndicatorsModel>(uri, 0, 1, "VisibleIndicatorsModel");
58+ qmlRegisterType<SharedUnityMenuModel>(uri, 0, 1, "SharedUnityMenuModel");
54
59
55 qmlRegisterSingletonType<UnityMenuModelCache>(uri, 0, 1, "UnityMenuModelCache", menuModelCacheSingleton);
60 qmlRegisterSingletonType<UnityMenuModelCache>(uri, 0, 1, "UnityMenuModelCache", menuModelCacheSingleton);
56
61
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+UnityMenuModelCache* UnityMenuModelCache::theCache = nullptr;
26+
27+
28+UnityMenuModelCache* UnityMenuModelCache::singleton()
25{
29{
30+ if (!theCache) {
31+ theCache = new UnityMenuModelCache();
32+ }
33+ return theCache;
26}
34}
27
35
28−UnityMenuModelCache::~UnityMenuModelCache()
36+UnityMenuModelCache::UnityMenuModelCache(QObject* parent)
37+ : QObject(parent)
29{
38{
30}
39}
31
40
32−UnityMenuModel* UnityMenuModelCache::model(const QByteArray& bus,
41+QSharedPointer<UnityMenuModel> UnityMenuModelCache::model(const QByteArray& bus,
33− const QByteArray& path,
42+ const QByteArray& path,
34− const QVariantMap& actions)
43+ const QVariantMap& actions)
35{
44{
36 if (m_registry.contains(path))
45 if (m_registry.contains(path))
37 return m_registry[path];
46 return m_registry[path];
38
47
39− UnityMenuModel* menuModel = new UnityMenuModel;
48+ UnityMenuModel* model = new UnityMenuModel;
49+ QQmlEngine::setObjectOwnership(model, QQmlEngine::CppOwnership);
50+
51+ QSharedPointer<UnityMenuModel> menuModel(model);
40− connect(menuModel, &QObject::destroyed, this, [menuModel, this](QObject*) {
52+ connect(model, &QObject::destroyed, this, [this] {
41− QList<QByteArray> keys = m_registry.keys(menuModel);
53+ QMutableHashIterator<QByteArray, QWeakPointer<UnityMenuModel>> iter(m_registry);
42− Q_FOREACH(const QByteArray& key, keys) {
54+ while(iter.hasNext()) {
55+ auto keyVal = iter.next();
56+ if (keyVal.value().toStrongRef().isNull()) {
43− m_registry.remove(key);
57+ iter.remove();
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+11−6
@@ -24,6 +24,7 @@
24
24
25#include <QObject>
25#include <QObject>
26#include <QHash>
26#include <QHash>
27+#include <QWeakPointer>
27
28
28class UnityMenuModel;
29class UnityMenuModel;
29
30
@@ -32,15 +33,19 @@ class UNITYINDICATORS_EXPORT UnityMenuModelCache : public QObject
32 Q_OBJECT
33 Q_OBJECT
33public:
34public:
34 UnityMenuModelCache(QObject*parent=nullptr);
35 UnityMenuModelCache(QObject*parent=nullptr);
35− ~UnityMenuModelCache();
36
36
37+ static UnityMenuModelCache* singleton();
38+
37− Q_INVOKABLE UnityMenuModel* model(const QByteArray& bus,
39+ QSharedPointer<UnityMenuModel> model(const QByteArray& bus,
38− const QByteArray& path,
40+ const QByteArray& path,
39− const QVariantMap& actions);
41+ const QVariantMap& actions);
42+
43+ // for tests use
40 Q_INVOKABLE bool contains(const QByteArray& path);
44 Q_INVOKABLE bool contains(const QByteArray& path);
41
45
42−private:
46+protected:
43− QHash<QByteArray, UnityMenuModel*> m_registry;
47+ QHash<QByteArray, QWeakPointer<UnityMenuModel>> m_registry;
48+ static UnityMenuModelCache* theCache;
44};
49};
45
50
46#endif // UNITYMENUMODELCACHE_H
51#endif // UNITYMENUMODELCACHE_H
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+ 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
@@ -36,10 +36,10 @@ Item {
36 property alias menuModel: cachedModel.model
36 property alias menuModel: cachedModel.model
37 property alias rootActionState: rootAction
37 property alias rootActionState: rootAction
38
38
39− CachedUnityMenuModel {
39+ SharedUnityMenuModel {
40 id: cachedModel
40 id: cachedModel
41 busName: indicatorItem.busName
41 busName: indicatorItem.busName
42− actionsObjectPath: indicatorItem.actionsObjectPath
42+ actions: { "indicator": indicatorItem.actionsObjectPath }
43 menuObjectPath: indicatorItem.deviceMenuObjectPath
43 menuObjectPath: indicatorItem.deviceMenuObjectPath
44 }
44 }
45
45
tests/mocks/Unity/Indicators/CMakeLists.txt+1
@@ -16,6 +16,7 @@ set(IndicatorsFakeQml_SOURCES
16 fakeunitymenumodelcache.cpp
16 fakeunitymenumodelcache.cpp
17 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/indicators.h
17 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/indicators.h
18 ${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
19 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/unitymenumodelcache.cpp
20 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/unitymenumodelcache.cpp
20 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/unitymenumodelstack.cpp
21 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/unitymenumodelstack.cpp
21 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/visibleindicatorsmodel.cpp
22 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/visibleindicatorsmodel.cpp
tests/mocks/Unity/Indicators/fakeplugin.cpp+6−1
@@ -26,14 +26,17 @@
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 "sharedunitymenumodel.h"
29#include "fakeunitymenumodelcache.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 FakeUnityMenuModelCache;
39+ return FakeUnityMenuModelCache::singleton();
37}
40}
38
41
39void IndicatorsFakePlugin::registerTypes(const char * uri)
42void IndicatorsFakePlugin::registerTypes(const char * uri)
@@ -42,11 +45,13 @@ void IndicatorsFakePlugin::registerTypes(const char * uri)
42
45
43 // internal
46 // internal
44 qmlRegisterType<FakeIndicatorsModel>(uri, 0, 1, "FakeIndicatorsModel");
47 qmlRegisterType<FakeIndicatorsModel>(uri, 0, 1, "FakeIndicatorsModel");
48+ qRegisterMetaType<UnityMenuModel*>("UnityMenuModel*");
45
49
46 // external
50 // external
47 qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
51 qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
48 qmlRegisterType<UnityMenuModelStack>(uri, 0, 1, "UnityMenuModelStack");
52 qmlRegisterType<UnityMenuModelStack>(uri, 0, 1, "UnityMenuModelStack");
49 qmlRegisterType<VisibleIndicatorsModel>(uri, 0, 1, "VisibleIndicatorsModel");
53 qmlRegisterType<VisibleIndicatorsModel>(uri, 0, 1, "VisibleIndicatorsModel");
54+ qmlRegisterType<SharedUnityMenuModel>(uri, 0, 1, "SharedUnityMenuModel");
50
55
51 qmlRegisterSingletonType<FakeUnityMenuModelCache>(uri, 0, 1, "UnityMenuModelCache", menuModelCacheSingleton);
56 qmlRegisterSingletonType<FakeUnityMenuModelCache>(uri, 0, 1, "UnityMenuModelCache", menuModelCacheSingleton);
52
57
tests/mocks/Unity/Indicators/fakeunitymenumodelcache.cpp+13−2
@@ -21,6 +21,14 @@
21#include <unitymenumodel.h>
21#include <unitymenumodel.h>
22#include <QDebug>
22#include <QDebug>
23
23
24+UnityMenuModelCache* FakeUnityMenuModelCache::singleton()
25+{
26+ if (!theCache) {
27+ theCache = new UnityMenuModelCache();
28+ }
29+ return theCache;
30+}
31+
24FakeUnityMenuModelCache::FakeUnityMenuModelCache(QObject* parent)
32FakeUnityMenuModelCache::FakeUnityMenuModelCache(QObject* parent)
25 : UnityMenuModelCache(parent)
33 : UnityMenuModelCache(parent)
26{
34{
@@ -31,6 +39,9 @@ void FakeUnityMenuModelCache::setCachedModelData(const QByteArray& bus,
31 const QVariantMap& actions,
39 const QVariantMap& actions,
32 const QVariantMap& properties)
40 const QVariantMap& properties)
33{
41{
42+ // keep a ref forever!
43+ if (!m_models.contains(path)) {
34− UnityMenuModel* menuModel = model(bus, path, actions);
44+ m_models[path] = model(bus, path, actions);
45+ }
35− menuModel->setRootProperties(properties);
46+ m_models[path]->setRootProperties(properties);
36}
47}
tests/mocks/Unity/Indicators/fakeunitymenumodelcache.h+7
@@ -22,16 +22,23 @@
22
22
23#include "unitymenumodelcache.h"
23#include "unitymenumodelcache.h"
24
24
25+#include <QHash>
26+
25class FakeUnityMenuModelCache : public UnityMenuModelCache
27class FakeUnityMenuModelCache : public UnityMenuModelCache
26{
28{
27 Q_OBJECT
29 Q_OBJECT
28public:
30public:
29 FakeUnityMenuModelCache(QObject*parent=nullptr);
31 FakeUnityMenuModelCache(QObject*parent=nullptr);
30
32
33+ static UnityMenuModelCache* singleton();
34+
31 Q_INVOKABLE void setCachedModelData(const QByteArray& bus,
35 Q_INVOKABLE void setCachedModelData(const QByteArray& bus,
32 const QByteArray& path,
36 const QByteArray& path,
33 const QVariantMap& actions,
37 const QVariantMap& actions,
34 const QVariantMap& properties);
38 const QVariantMap& properties);
39+
40+private:
41+ QHash<QByteArray, QSharedPointer<UnityMenuModel>> m_models;
35};
42};
36
43
37#endif // FAKEUNITYMENUMODELCACHE_H
44#endif // FAKEUNITYMENUMODELCACHE_H
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+92
@@ -0,0 +1,92 @@
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+};
90+
91+QTEST_GUILESS_MAIN(SharedUnityMenuModelTest)
92+#include "sharedunitymenumodeltest.moc"
tests/qmltests/CMakeLists.txt−1
@@ -81,7 +81,6 @@ add_qml_test(Panel/New NewIndicatorsRow ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BIN
81add_qml_test(Panel/New NewIndicatorsBar ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
81add_qml_test(Panel/New NewIndicatorsBar ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
82add_qml_test(Panel/Indicators DefaultIndicatorWidget ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
82add_qml_test(Panel/Indicators DefaultIndicatorWidget ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
83add_qml_test(Panel/Indicators DefaultIndicatorPage ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
83add_qml_test(Panel/Indicators DefaultIndicatorPage ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
84−add_qml_test(Panel/Indicators CachedUnityMenuModel ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
85# These MenuItemFactory tests need the test/mocks/ to come before plugins/
84# These MenuItemFactory tests need the test/mocks/ to come before plugins/
86add_qml_test(Panel/Indicators MenuItemFactory IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks ${qmltest_DEFAULT_IMPORT_PATHS})
85add_qml_test(Panel/Indicators MenuItemFactory IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks ${qmltest_DEFAULT_IMPORT_PATHS})
87add_qml_test(Panel/Indicators MessageMenuItemFactory IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks ${qmltest_DEFAULT_IMPORT_PATHS})
86add_qml_test(Panel/Indicators MessageMenuItemFactory IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks ${qmltest_DEFAULT_IMPORT_PATHS})
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−}