on xenial help sign in
Indicator visibility moved to VisibilityModel.
commitdb61a4cd89cb20bddb6da8f42b21df0ea490a2e3 authorNick Dedekind <nicholas.dedekind@gmail.com> dateThu 29 Aug 2013, 15:00 (13 years ago) parent8ba4976
22 files changed+536−169
Panel/IndicatorItem.qml−1 Panel/IndicatorRow.qml+6−8 Panel/Indicators.qml+16−2 Panel/MenuContent.qml+6−18 plugins/Unity/Indicators/CMakeLists.txt+2 plugins/Unity/Indicators/cachedunitymenumodel.cpp+103 plugins/Unity/Indicators/cachedunitymenumodel.h+66 plugins/Unity/Indicators/indicator.cpp+33−17 plugins/Unity/Indicators/indicator.h+4−5 plugins/Unity/Indicators/indicatorsmanager.cpp+4−7 plugins/Unity/Indicators/indicatorsmodel.cpp+16−31 plugins/Unity/Indicators/indicatorsmodel.h+1−3 plugins/Unity/Indicators/plugin.cpp+5−1 plugins/Unity/Indicators/qml/CachedUnityMenuModel.qml−60 plugins/Unity/Indicators/qml/IndicatorBase.qml+3−3 plugins/Unity/Indicators/qml/qmldir−1 plugins/Unity/Indicators/rootactionstate.cpp+14−10 plugins/Unity/Indicators/rootactionstate.h+3−1 plugins/Unity/Indicators/unitymenumodelcache.cpp+7−1 plugins/Unity/Indicators/unitymenumodelcache.h+2 plugins/Unity/Indicators/visibleindicatorsmodel.cpp+173 plugins/Unity/Indicators/visibleindicatorsmodel.h+72
Panel/IndicatorItem.qml−1
@@ -26,7 +26,6 @@ Item {
2626 property bool highlighted: false
2727 property bool dimmed: false
2828 property var indicatorProperties: undefined
29− property bool indicatorVisible: loader.item != undefined && loader.status == Loader.Ready ? loader.item.enabled : false
3029
3130 opacity: dimmed ? 0.4 : 1
3231 Behavior on opacity { StandardAnimation {} }
Panel/IndicatorRow.qml+6−8
@@ -53,11 +53,16 @@ Item {
5353 objectName: "rowRepeater"
5454 model: indicatorsModel ? indicatorsModel : undefined
5555
56+ onItemRemoved: {
57+ if (currentItemIndex == -1) {
58+ setDefaultItem(0);
59+ }
60+ }
61+
5662 Item {
5763 id: itemWrapper
5864 height: indicatorRow.height
5965 width: indicatorItem.width
60− visible: indicatorItem.indicatorVisible
6166
6267 property int ownIndex: index
6368 property alias highlighted: indicatorItem.highlighted
@@ -72,13 +77,6 @@ Item {
7277
7378 widgetSource: model.widgetSource
7479 indicatorProperties : model.indicatorProperties
75−
76− Component.onCompleted: {
77− indicatorsModel.setData(index, indicatorVisible, Indicators.IndicatorsModelRole.IsVisible);
78− }
79− onIndicatorVisibleChanged: {
80− indicatorsModel.setData(index, indicatorVisible, Indicators.IndicatorsModelRole.IsVisible);
81− }
8280 }
8381
8482 opacity: {
Panel/Indicators.qml+16−2
@@ -17,6 +17,8 @@
1717import QtQuick 2.0
1818import Ubuntu.Components 0.1
1919import Ubuntu.Gestures 0.1
20+import Unity.Indicators 0.1 as Indicators
21+import Utils 0.1
2022
2123import "../Components"
2224import "../Components/ListItems"
@@ -175,7 +177,7 @@ Showable {
175177 top: indicatorRow.bottom
176178 bottom: handle.top
177179 }
178− indicatorsModel: indicatorsModel
180+ indicatorsModel: filteredIndicators
179181 clip: !indicators.fullyOpened
180182 activeHeader: indicators.state == "hint" || indicators.state == "reveal"
181183
@@ -249,6 +251,18 @@ Showable {
249251 id: indicatorsModel
250252 }
251253
254+ SortFilterProxyModel {
255+ id: filteredIndicators
256+ model: Indicators.VisibleIndicatorsModel {
257+ model: indicatorsModel
258+ profile: "phone"
259+ }
260+ dynamicSortFilter: true
261+
262+ filterRole: Indicators.IndicatorsModelRole.IsVisible
263+ filterRegExp: RegExp("^true$")
264+ }
265+
252266 IndicatorRow {
253267 id: indicatorRow
254268 objectName: "indicatorRow"
@@ -257,7 +271,7 @@ Showable {
257271 right: parent.right
258272 }
259273 height: indicators.panelHeight
260− indicatorsModel: indicatorsModel
274+ indicatorsModel: filteredIndicators
261275 state: indicators.state
262276
263277 Connections {
Panel/MenuContent.qml+6−18
@@ -17,7 +17,6 @@
1717import QtQuick 2.0
1818import Ubuntu.Components 0.1
1919import Unity.Indicators 0.1 as Indicators
20−import Utils 0.1
2120import "../Components"
2221
2322// FIXME : We dont want to use MainView.
@@ -28,7 +27,7 @@ MainView {
2827
2928 property QtObject indicatorsModel: null
3029 property bool __contentActive: false
31− readonly property int currentMenuIndex : filteredIndicators.mapToSource(tabs.selectedTabIndex)
30+ readonly property int currentMenuIndex : tabs.selectedTabIndex
3231 backgroundColor: "#221e1c" // FIXME not in palette yet
3332 property int contentReleaseInterval: 20000
3433 property bool activeHeader: false
@@ -37,13 +36,11 @@ MainView {
3736 height: units.gu(42)
3837
3938 function setCurrentMenuIndex(index) {
40− var filteredIndex = filteredIndicators.mapFromSource(index)
41−
42− if (tabs.selectedTabIndex !== filteredIndex) {
39+ if (tabs.selectedTabIndex !== index) {
4340 if (tabs.selectedTabIndex == -1) {
4441 tabs.tabBar.animate = false;
4542 }
46− tabs.selectedTabIndex = filteredIndex;
43+ tabs.selectedTabIndex = index;
4744 tabs.tabBar.animate = true;
4845 }
4946 }
@@ -64,15 +61,6 @@ MainView {
6461 tabs.tabBar.alwaysSelectionMode = activeHeader;
6562 }
6663
67− SortFilterProxyModel {
68− id: filteredIndicators
69− model: indicatorsModel
70− dynamicSortFilter: true
71−
72− filterRole: Indicators.IndicatorsModelRole.IsVisible
73− filterRegExp: RegExp("^true$")
74− }
75−
7664 Tabs {
7765 id: tabs
7866 objectName: "tabs"
@@ -81,8 +69,8 @@ MainView {
8169
8270 Repeater {
8371 id: repeater
84− model: filteredIndicators
85− objectName: "menus"
72+ model: indicatorsModel
73+ objectName: "tabsRepeater"
8674
8775 // FIXME: This is needed because tabs dont handle repeaters well.
8876 // Due to the child ordering happening after child insertion.
@@ -126,7 +114,7 @@ MainView {
126114 item[pName] = indicatorProperties[pName]
127115 }
128116 }
129− if (contentActive && menus.visible) {
117+ if (contentActive && tabs.visible) {
130118 item.start()
131119 }
132120 }
plugins/Unity/Indicators/CMakeLists.txt+2
@@ -24,6 +24,7 @@ include_directories(
2424)
2525
2626set(IndicatorsQML_SOURCES
27+ cachedunitymenumodel.cpp
2728 indicator.cpp
2829 indicators.h
2930 indicatorsmanager.cpp
@@ -34,6 +35,7 @@ set(IndicatorsQML_SOURCES
3435 rootactionstate.cpp
3536 unitymenumodelcache.cpp
3637 unitymenumodelstack.cpp
38+ visibleindicatorsmodel.cpp
3739)
3840add_definitions(-DUNITYINDICATORS_LIBRARY)
3941
plugins/Unity/Indicators/cachedunitymenumodel.cppnew file+103
@@ -0,0 +1,103 @@
1+/*
2+ * Copyright (C) 2012, 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+// self
21+#include "cachedunitymenumodel.h"
22+#include "unitymenumodelcache.h"
23+
24+#include <unitymenumodel.h>
25+
26+CachedUnityMenuModel::CachedUnityMenuModel(QObject* parent)
27+ : QObject(parent),
28+ m_model(NULL)
29+{
30+}
31+
32+CachedUnityMenuModel::~CachedUnityMenuModel()
33+{
34+}
35+
36+UnityMenuModel* CachedUnityMenuModel::model() const
37+{
38+ return m_model;
39+}
40+
41+QString CachedUnityMenuModel::busName() const
42+{
43+ return m_busName;
44+}
45+
46+void CachedUnityMenuModel::setBusName(const QString &name)
47+{
48+ if (m_busName != name) {
49+ m_busName = name;
50+ Q_EMIT busNameChanged(m_busName);
51+
52+ if (m_model && m_model->busName() != m_busName) {
53+ m_model->setBusName(m_busName.toUtf8());
54+ }
55+ }
56+}
57+
58+QVariantMap CachedUnityMenuModel::actions() const
59+{
60+ return m_model->actions();
61+}
62+
63+void CachedUnityMenuModel::setActions(const QVariantMap &actions)
64+{
65+ if (m_actions != actions) {
66+ m_actions = actions;
67+ Q_EMIT actionsChanged(m_actions);
68+
69+ if (m_model && m_model->actions() != m_actions) {
70+ m_model->setActions(m_actions);
71+ }
72+ }
73+}
74+
75+QString CachedUnityMenuModel::menuObjectPath() const
76+{
77+ return m_model->menuObjectPath();
78+}
79+
80+void CachedUnityMenuModel::setMenuObjectPath(const QString &path)
81+{
82+ if (m_menuObjectPath != path) {
83+ m_model = NULL;
84+
85+ m_menuObjectPath = path;
86+ Q_EMIT menuObjectPathChanged(m_menuObjectPath);
87+
88+ // create new model.
89+ if (!m_menuObjectPath.isEmpty()) {
90+ m_model = UnityMenuModelCache::cache()->model(m_menuObjectPath);
91+ if (!m_model) {
92+ m_model = new UnityMenuModel;
93+ if (!m_busName.isEmpty()) m_model->setBusName(m_busName.toUtf8());
94+ if (!m_actions.isEmpty()) m_model->setActions(m_actions);
95+ m_model->setMenuObjectPath(m_menuObjectPath.toUtf8());
96+
97+ UnityMenuModelCache::cache()->registerModel(m_menuObjectPath, m_model);
98+ }
99+ }
100+
101+ Q_EMIT modelChanged(m_model);
102+ }
103+}
plugins/Unity/Indicators/cachedunitymenumodel.hnew file+66
@@ -0,0 +1,66 @@
1+/*
2+ * Copyright (C) 2012, 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+#ifndef CACHEDUNITYMENUMODEL_H
21+#define CACHEDUNITYMENUMODEL_H
22+
23+ #include <QObject>
24+ #include <QVariantMap>
25+
26+class UnityMenuModel;
27+
28+class CachedUnityMenuModel : public QObject
29+{
30+ Q_OBJECT
31+
32+ Q_PROPERTY(UnityMenuModel* model READ model NOTIFY modelChanged)
33+ Q_PROPERTY(QString busName READ busName WRITE setBusName NOTIFY busNameChanged)
34+ Q_PROPERTY(QVariantMap actions READ actions WRITE setActions NOTIFY actionsChanged)
35+ Q_PROPERTY(QString menuObjectPath READ menuObjectPath WRITE setMenuObjectPath NOTIFY menuObjectPathChanged)
36+
37+public:
38+ explicit CachedUnityMenuModel(QObject *parent = 0);
39+ CachedUnityMenuModel(UnityMenuModel* model);
40+ ~CachedUnityMenuModel();
41+
42+ UnityMenuModel* model() const;
43+
44+ QString busName() const;
45+ void setBusName(const QString &name);
46+
47+ QVariantMap actions() const;
48+ void setActions(const QVariantMap &actions);
49+
50+ QString menuObjectPath() const;
51+ void setMenuObjectPath(const QString &path);
52+
53+Q_SIGNALS:
54+ void modelChanged(UnityMenuModel* model);
55+ void busNameChanged(const QString& busName);
56+ void actionsChanged(const QVariantMap& action);
57+ void menuObjectPathChanged(const QString& menuObjectPath);
58+
59+private:
60+ UnityMenuModel* m_model;
61+ QString m_busName;
62+ QVariantMap m_actions;
63+ QString m_menuObjectPath;
64+};
65+
66+#endif // CACHEDUNITYMENUMODEL_H
plugins/Unity/Indicators/indicator.cpp+33−17
@@ -18,18 +18,21 @@
1818 */
1919
2020#include "indicator.h"
21+#include "cachedunitymenumodel.h"
2122
2223#include <QStringList>
24+#include <unitymenumodel.h>
2325
2426Indicator::Indicator(QObject *parent)
2527 : QObject(parent),
26− m_position(0),
27− m_visible(false)
28+ m_position(0)
2829{
2930}
3031
3132Indicator::~Indicator()
3233{
34+ qDeleteAll(m_cachedModels);
35+ m_cachedModels.clear();
3336}
3437
3538void Indicator::init(const QString& busName, const QSettings& settings)
@@ -87,21 +90,6 @@ void Indicator::setPosition(int position)
8790 }
8891}
8992
90−bool Indicator::isVisible() const
91−{
92− return m_visible;
93−}
94−
95−bool Indicator::setVisible(bool visible)
96−{
97− if (visible != m_visible) {
98− m_visible = visible;
99− Q_EMIT visibleChanged(m_visible);
100− return true;
101− }
102− return false;
103−}
104−
10593QVariant Indicator::indicatorProperties() const
10694{
10795 return m_properties;
@@ -115,3 +103,31 @@ void Indicator::setIndicatorProperties(const QVariant &properties)
115103 Q_EMIT indicatorPropertiesChanged(m_properties);
116104 }
117105}
106+
107+QAbstractItemModel* Indicator::getMenuModel(const QString& profile)
108+{
109+ QVariantMap propMap = m_properties.toMap();
110+ QString busName = propMap["busName"].toString();
111+ QString actionsObjectPath = propMap["actionsObjectPath"].toString();
112+
113+ QVariantMap menuObjectPaths = propMap["menuObjectPaths"].toMap();
114+ if (!menuObjectPaths.contains(profile)) {
115+ return NULL;
116+ }
117+
118+ QString menuObjectPath = menuObjectPaths[profile].toString();
119+
120+ CachedUnityMenuModel* cachedModel;
121+ if (!m_cachedModels.contains(profile)) {
122+ cachedModel = new CachedUnityMenuModel();
123+ m_cachedModels[profile] = cachedModel;
124+ } else {
125+ cachedModel = m_cachedModels[profile];
126+ }
127+ cachedModel->setBusName(busName);
128+ cachedModel->setMenuObjectPath(menuObjectPath);
129+ QVariantMap actions; actions["indicator"] = actionsObjectPath;
130+ cachedModel->setActions(actions);
131+
132+ return cachedModel->model();
133+}
plugins/Unity/Indicators/indicator.h+4−5
@@ -25,6 +25,8 @@
2525
2626#include <QObject>
2727#include <QSettings>
28+class QAbstractItemModel;
29+class CachedUnityMenuModel;
2830
2931class UNITYINDICATORS_EXPORT Indicator : public QObject
3032{
@@ -40,15 +42,12 @@ public:
4042 QString identifier() const;
4143 int position() const;
4244 QVariant indicatorProperties() const;
43− bool isVisible() const;
4445
45− // is set once we know if we're connected.
46− bool setVisible(bool visible);
46+ QAbstractItemModel* getMenuModel(const QString& profile);
4747
4848Q_SIGNALS:
4949 void identifierChanged(const QString &identifier);
5050 void positionChanged(int position);
51− void visibleChanged(bool visible);
5251 void indicatorPropertiesChanged(const QVariant &properties);
5352
5453protected:
@@ -59,8 +58,8 @@ protected:
5958private:
6059 QString m_identifier;
6160 int m_position;
62− bool m_visible;
6361 QVariant m_properties;
62+ QHash<QString, CachedUnityMenuModel*> m_cachedModels;
6463};
6564
6665#endif // INDICATOR_H
plugins/Unity/Indicators/indicatorsmanager.cpp+4−7
@@ -214,14 +214,11 @@ void IndicatorsManager::unloadFile(const QFileInfo& file)
214214 IndicatorData* data = iter.value();
215215 if (data->m_fileInfo.absoluteFilePath() == file.absoluteFilePath())
216216 {
217− if (!data->m_verified)
218− {
219− QString name = data->m_name;
220− Q_EMIT indicatorAboutToBeUnloaded(name);
217+ QString name = data->m_name;
218+ Q_EMIT indicatorAboutToBeUnloaded(name);
221219
222− delete data;
223− iter.remove();
224− }
220+ delete data;
221+ iter.remove();
225222 }
226223 }
227224
plugins/Unity/Indicators/indicatorsmodel.cpp+16−31
@@ -229,9 +229,9 @@ QVariant IndicatorsModel::defaultData(Indicator::Ptr indicator, int role)
229229 case IndicatorsModelRole::Description:
230230 return "";
231231 case IndicatorsModelRole::WidgetSource:
232− return shellAppDirectory()+"/Panel/Indicators/DefaultIndicatorWidget2.qml";
232+ return shellAppDirectory()+"/Panel/Indicators/DefaultIndicatorWidget.qml";
233233 case IndicatorsModelRole::PageSource:
234− return shellAppDirectory()+"/Panel/Indicators/DefaultIndicatorPage2.qml";
234+ return shellAppDirectory()+"/Panel/Indicators/DefaultIndicatorPage.qml";
235235 }
236236 return QVariant();
237237}
@@ -270,7 +270,7 @@ QVariant IndicatorsModel::data(const QModelIndex &index, int role) const
270270 }
271271 break;
272272 case IndicatorsModelRole::IsVisible:
273− return (indicator ? indicator->isVisible() : false);
273+ return true;
274274 case IndicatorsModelRole::Title:
275275 case IndicatorsModelRole::Description:
276276 case IndicatorsModelRole::WidgetSource:
@@ -282,34 +282,6 @@ QVariant IndicatorsModel::data(const QModelIndex &index, int role) const
282282 return QVariant();
283283}
284284
285−void IndicatorsModel::setData(int row, const QVariant& value, int role)
286−{
287− setData(index(row, 0), value, role);
288−}
289−
290−bool IndicatorsModel::setData(const QModelIndex & index, const QVariant & value, int role)
291−{
292− if (!index.isValid() || index.row() >= m_indicators.size())
293− return false;
294−
295− Indicator::Ptr indicator = m_indicators[index.row()];
296−
297− switch (role)
298− {
299− case IndicatorsModelRole::IsVisible:
300− if (indicator) {
301− if (indicator->setVisible(value.toBool())) {
302− dataChanged(index, index, QVector<int>() << role);
303− }
304− return true;
305− }
306− break;
307− default:
308− break;
309− }
310− return false;
311−}
312−
313285QVariant IndicatorsModel::indicatorData(const Indicator::Ptr& indicator, int role) const
314286{
315287 if (indicator && m_parsed_indicator_data.contains(indicator->identifier()))
@@ -352,3 +324,16 @@ QVariant IndicatorsModel::indicatorData() const
352324{
353325 return m_indicator_data;
354326}
327+
328+QAbstractItemModel* IndicatorsModel::getMenuModelForIndexProfile(const QModelIndex& index, const QString& device) const
329+{
330+ if (!index.isValid() || index.row() >= m_indicators.size())
331+ return NULL;
332+
333+ Indicator::Ptr indicator = m_indicators[index.row()];
334+ if (!indicator) {
335+ return NULL;
336+ }
337+
338+ return indicator->getMenuModel(device);
339+}
plugins/Unity/Indicators/indicatorsmodel.h+1−3
@@ -37,7 +37,6 @@ class UNITYINDICATORS_EXPORT IndicatorsModel : public QAbstractListModel
3737 Q_PROPERTY(QVariant indicatorData READ indicatorData WRITE setIndicatorData NOTIFY indicatorDataChanged)
3838
3939public:
40−
4140 IndicatorsModel(QObject *parent=0);
4241 ~IndicatorsModel();
4342
@@ -45,19 +44,18 @@ public:
4544 Q_INVOKABLE void unload();
4645
4746 Q_INVOKABLE QVariant data(int row, int role) const;
48− Q_INVOKABLE void setData(int row, const QVariant& value, int role);
4947
5048 /* QAbstractItemModel */
5149 QHash<int, QByteArray> roleNames() const;
5250 int columnCount(const QModelIndex &parent = QModelIndex()) const;
5351 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
54− bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole);
5552 QModelIndex parent (const QModelIndex &index) const;
5653 int rowCount(const QModelIndex &parent = QModelIndex()) const;
5754
5855 void setIndicatorData(const QVariant& data);
5956 QVariant indicatorData() const;
6057
58+ QAbstractItemModel* getMenuModelForIndexProfile(const QModelIndex& index, const QString& profile) const;
6159
6260Q_SIGNALS:
6361 void countChanged();
plugins/Unity/Indicators/plugin.cpp+5−1
@@ -32,21 +32,25 @@
3232#include "rootactionstate.h"
3333#include "unitymenumodelcache.h"
3434#include "unitymenumodelstack.h"
35+#include "visibleindicatorsmodel.h"
36+#include "cachedunitymenumodel.h"
3537
3638static QObject* menuModelCacheSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
3739 Q_UNUSED(engine);
3840 Q_UNUSED(scriptEngine);
39− return new UnityMenuModelCache;
41+ return UnityMenuModelCache::cache();
4042}
4143
4244void Indicators2Plugin::registerTypes(const char *uri)
4345{
4446 qmlRegisterType<IndicatorsManager>(uri, 0, 1, "IndicatorsManager");
4547 qmlRegisterType<IndicatorsModel>(uri, 0, 1, "IndicatorsModel");
48+ qmlRegisterType<VisibleIndicatorsModel>(uri, 0, 1, "VisibleIndicatorsModel");
4649 qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
4750 qmlRegisterType<UnityMenuModelStack>(uri, 0, 1, "UnityMenuModelStack");
4851 qmlRegisterType<RootActionState>(uri, 0, 1, "RootActionState");
4952 qmlRegisterType<ModelPrinter>(uri, 0, 1, "ModelPrinter");
53+ qmlRegisterType<CachedUnityMenuModel>(uri, 0, 1, "CachedUnityMenuModel");
5054
5155 qmlRegisterSingletonType<UnityMenuModelCache>(uri, 0, 1, "UnityMenuModelCache", menuModelCacheSingleton);
5256
plugins/Unity/Indicators/qml/CachedUnityMenuModel.qmldeleted−60
@@ -1,60 +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 as QMenuModel
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−
31− readonly property bool ready: busName!=="" && actionsObjectPath!=="" && menuObjectPath!==""
32−
33− property QtObject model: {
34− if (!ready) {
35− return null;
36− }
37−
38− var component = Indicators.UnityMenuModelCache.model(menuObjectPath);
39− if (!component) {
40− component = modelComponent.createObject(cachedModel);
41− return component;
42− }
43− return component;
44− }
45−
46− Component {
47− id: modelComponent
48−
49− QMenuModel.UnityMenuModel {
50− id: unityModel
51− busName: cachedModel.busName
52− actions: { "indicator": cachedModel.actionsObjectPath }
53− menuObjectPath: cachedModel.menuObjectPath
54−
55− Component.onCompleted: {
56− Indicators.UnityMenuModelCache.registerModel(cachedModel.menuObjectPath, unityModel);
57− }
58− }
59− }
60−}
plugins/Unity/Indicators/qml/IndicatorBase.qml+3−3
@@ -39,10 +39,10 @@ Item {
3939
4040 property alias menuModel: cachedModel.model
4141
42− CachedUnityMenuModel {
42+ Indicators.CachedUnityMenuModel {
4343 id: cachedModel
44− busName: active ? indicatorItem.busName : ""
45− actionsObjectPath: active ? indicatorItem.actionsObjectPath : ""
44+ busName: indicatorItem.busName
45+ actions: { "indicator": indicatorItem.actionsObjectPath }
4646 menuObjectPath: active ? indicatorItem.deviceMenuObjectPath : ""
4747 }
4848}
plugins/Unity/Indicators/qml/qmldir−1
@@ -4,7 +4,6 @@ typeinfo plugin.qmltypes
44
55BaseMenuItem 0.1 BaseMenuItem.qml
66ButtonMenuItem 0.1 ButtonMenuItem.qml
7−CachedUnityMenuModel 0.1 CachedUnityMenuModel.qml
87DivMenuItem 0.1 DivMenuItem.qml
98FramedMenuItem 0.1 FramedMenuItem.qml
109HLine 0.1 HLine.qml
plugins/Unity/Indicators/rootactionstate.cpp+14−10
@@ -31,7 +31,7 @@ extern "C" {
3131
3232RootActionState::RootActionState(QObject *parent)
3333 : ActionStateParser(parent),
34− m_menu(NULL)
34+ m_manageParserParent(false)
3535{
3636}
3737
@@ -47,18 +47,17 @@ UnityMenuModel* RootActionState::menu() const
4747void RootActionState::setMenu(UnityMenuModel* menu)
4848{
4949 if (m_menu != menu) {
50− if (m_menu) {
50+ if (!m_menu.isNull()) {
5151 m_menu->disconnect(this);
5252 }
5353 m_menu = menu;
5454
55− if (m_menu) {
56− connect(m_menu, SIGNAL(rowsInserted(const QModelIndex&, int, int)), SLOT(onModelRowsAdded(const QModelIndex&, int, int)));
57− connect(m_menu, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), SLOT(onModelRowsRemoved(const QModelIndex&, int, int)));
58− connect(m_menu, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)), SLOT(onModelDataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)));
59−
60− m_menu->setActionStateParser(this);
55+ if (menu) {
56+ connect(menu, SIGNAL(rowsInserted(const QModelIndex&, int, int)), SLOT(onModelRowsAdded(const QModelIndex&, int, int)));
57+ connect(menu, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), SLOT(onModelRowsRemoved(const QModelIndex&, int, int)));
58+ connect(menu, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)), SLOT(onModelDataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)));
6159 }
60+
6261 updateActionState();
6362 Q_EMIT menuChanged();
6463 }
@@ -94,8 +93,13 @@ void RootActionState::onModelDataChanged(const QModelIndex& topLeft, const QMode
9493
9594void RootActionState::updateActionState()
9695{
97− if (m_menu && m_menu->rowCount() > 0) {
96+ if (!m_menu.isNull() && m_menu->rowCount() > 0) {
97+ ActionStateParser* oldParser = m_menu->actionStateParser();
98+ m_menu->setActionStateParser(this);
99+
98100 m_cachedState = m_menu->get(0, "actionState").toMap();
101+
102+ m_menu->setActionStateParser(oldParser);
99103 } else {
100104 m_cachedState.clear();
101105 }
@@ -105,7 +109,7 @@ void RootActionState::updateActionState()
105109
106110bool RootActionState::isValid() const
107111{
108− return m_menu && m_menu->rowCount() > 0;
112+ return !m_menu.isNull() && m_menu->rowCount() > 0;
109113}
110114
111115QString RootActionState::label() const
plugins/Unity/Indicators/rootactionstate.h+3−1
@@ -23,6 +23,7 @@
2323#include "unityindicatorsglobal.h"
2424
2525#include <actionstateparser.h>
26+#include <QPointer>
2627
2728class UnityMenuModel;
2829
@@ -75,8 +76,9 @@ private Q_SLOTS:
7576private:
7677 void updateActionState();
7778
78− UnityMenuModel* m_menu;
79+ QPointer<UnityMenuModel> m_menu;
7980 QVariantMap m_cachedState;
81+ bool m_manageParserParent;
8082};
8183
8284#endif // ROOTACTIONSTATE_H
plugins/Unity/Indicators/unitymenumodelcache.cpp+7−1
@@ -39,4 +39,10 @@ void UnityMenuModelCache::registerModel(const QString& path, UnityMenuModel* men
3939{
4040 menuModel->setParent(this);
4141 m_menuModels[path] = menuModel;
42−}
42+}
43+
44+UnityMenuModelCache* UnityMenuModelCache::cache()
45+{
46+ static UnityMenuModelCache* model = new UnityMenuModelCache;
47+ return model;
48+}
plugins/Unity/Indicators/unitymenumodelcache.h+2
@@ -37,6 +37,8 @@ public:
3737 Q_INVOKABLE UnityMenuModel* model(const QString& path) const;
3838 Q_INVOKABLE void registerModel(const QString& path, UnityMenuModel* menuModel);
3939
40+ static UnityMenuModelCache* cache();
41+
4042private:
4143 QHash<QString, UnityMenuModel*> m_menuModels;
4244};
plugins/Unity/Indicators/visibleindicatorsmodel.cppnew file+173
@@ -0,0 +1,173 @@
1+/*
2+ * Copyright (C) 2012, 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+// self
18+#include "visibleindicatorsmodel.h"
19+#include "rootactionstate.h"
20+#include "indicatorsmodel.h"
21+#include "indicators.h"
22+
23+#include <unitymenumodel.h>
24+
25+// Qt
26+#include <QDebug>
27+
28+VisibleIndicatorsModel::VisibleIndicatorsModel(QObject *parent)
29+ : QIdentityProxyModel(parent),
30+ m_model(NULL)
31+{
32+ connect(this, SIGNAL(modelReset()), SIGNAL(countChanged()));
33+ connect(this, SIGNAL(rowsInserted(QModelIndex,int,int)), SIGNAL(countChanged()));
34+ connect(this, SIGNAL(rowsRemoved(QModelIndex,int,int)), SIGNAL(countChanged()));
35+}
36+
37+VisibleIndicatorsModel::~VisibleIndicatorsModel()
38+{
39+ qDeleteAll(m_rootActions);
40+ m_rootActions.clear();
41+ m_visible.clear();
42+}
43+
44+QHash<int, QByteArray> VisibleIndicatorsModel::roleNames() const
45+{
46+ return sourceModel() ? sourceModel()->roleNames() : QHash<int, QByteArray>();
47+}
48+
49+QByteArray VisibleIndicatorsModel::profile() const
50+{
51+ return m_profile;
52+}
53+
54+void VisibleIndicatorsModel::setProfile(const QByteArray& profile)
55+{
56+ if (m_profile != profile) {
57+ m_profile = profile;
58+ Q_EMIT profileChanged();
59+ }
60+}
61+
62+IndicatorsModel* VisibleIndicatorsModel::model() const
63+{
64+ return m_model;
65+}
66+
67+void VisibleIndicatorsModel::setModel(IndicatorsModel *itemModel)
68+{
69+ if (itemModel != m_model) {
70+ m_model = itemModel;
71+ if (sourceModel() != NULL) {
72+ sourceModel()->disconnect(this);
73+ }
74+
75+ setSourceModel(itemModel);
76+
77+ if (sourceModel() != NULL) {
78+ // ... and use our own
79+ connect(sourceModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
80+ SLOT(sourceRowsInserted(QModelIndex,int,int)));
81+ connect(sourceModel(), SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
82+ SLOT(sourceRowsAboutToBeRemoved(QModelIndex,int,int)));
83+ connect(sourceModel(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
84+ SLOT(sourceDataChanged(QModelIndex,QModelIndex)));
85+ }
86+ Q_EMIT modelChanged();
87+ }
88+}
89+
90+void VisibleIndicatorsModel::sourceRowsInserted(const QModelIndex&, int start, int end)
91+{
92+ if (!m_model) {
93+ return;
94+ }
95+
96+ for (int row = start; row <= end; row++) {
97+ const QModelIndex idx = sourceModel()->index(row, 0);
98+ if (!idx.isValid()) {
99+ continue;
100+ }
101+
102+ RootActionState* actionState = new RootActionState();
103+ connect(actionState, SIGNAL(updated()), SLOT(onActionStateUpdated()));
104+ m_rootActions.insert(row, actionState);
105+ m_visible.insert(row, false);
106+
107+ UnityMenuModel* unityModel = qobject_cast<UnityMenuModel*>(m_model->getMenuModelForIndexProfile(idx, profile()));
108+ actionState->setMenu(unityModel);
109+ }
110+}
111+
112+void VisibleIndicatorsModel::sourceRowsAboutToBeRemoved(const QModelIndex&, int start, int end)
113+{
114+ for (int row = start; row <= end; row++) {
115+
116+ if (m_rootActions.count() > start) {
117+ delete m_rootActions[start];
118+ m_rootActions.removeAt(start);
119+ }
120+ if (m_visible.count() > start) {
121+ m_visible.removeAt(start);
122+ }
123+ }
124+}
125+
126+void VisibleIndicatorsModel::sourceDataChanged(const QModelIndex& topRight, const QModelIndex& bottomRight)
127+{
128+ for (int row = topRight.row(); row <= bottomRight.row(); row++) {
129+
130+ const QModelIndex idx = sourceModel()->index(row, 0);
131+ if (!idx.isValid()) {
132+ continue;
133+ }
134+ if (m_rootActions.count() <= row) {
135+ break;
136+ }
137+
138+ UnityMenuModel* unityModel = qobject_cast<UnityMenuModel*>(m_model->getMenuModelForIndexProfile(idx, profile()));
139+ m_rootActions[row]->setMenu(unityModel);
140+ }
141+}
142+
143+void VisibleIndicatorsModel::onActionStateUpdated()
144+{
145+ RootActionState* actionState = qobject_cast<RootActionState*>(sender());
146+ int changedRow = m_rootActions.indexOf(actionState);
147+
148+ QModelIndex modelIndex = this->index(changedRow, 0);
149+ if (!modelIndex.isValid()) {
150+ return;
151+ }
152+
153+ while (m_visible.count() <= changedRow) {
154+ m_visible.append(false);
155+ }
156+
157+ if (actionState->isVisible() != m_visible[changedRow]) {
158+ m_visible[changedRow] = actionState->isVisible();
159+
160+ Q_EMIT dataChanged(modelIndex, modelIndex, QVector<int>() << IndicatorsModelRole::IsVisible);
161+ }
162+}
163+
164+QVariant VisibleIndicatorsModel::data(const QModelIndex &index, int role) const
165+{
166+ if (role != IndicatorsModelRole::IsVisible)
167+ return QIdentityProxyModel::data(index, role);
168+
169+ if (!index.isValid() || m_visible.count() <= index.row())
170+ return false;
171+
172+ return m_visible[index.row()];
173+}
plugins/Unity/Indicators/visibleindicatorsmodel.hnew file+72
@@ -0,0 +1,72 @@
1+/*
2+ * Copyright (C) 2012, 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+#ifndef VISIBLEINDICATORSMODEL_H
21+#define VISIBLEINDICATORSMODEL_H
22+
23+#include <QIdentityProxyModel>
24+#include <QPersistentModelIndex>
25+
26+class RootActionState;
27+class IndicatorsModel;
28+
29+class VisibleIndicatorsModel : public QIdentityProxyModel
30+{
31+ Q_OBJECT
32+
33+ Q_PROPERTY(IndicatorsModel* model READ model WRITE setModel NOTIFY modelChanged)
34+ Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
35+ Q_PROPERTY(QByteArray profile READ profile WRITE setProfile NOTIFY profileChanged)
36+
37+public:
38+ explicit VisibleIndicatorsModel(QObject *parent = 0);
39+ ~VisibleIndicatorsModel();
40+
41+ /* getters */
42+ QHash<int, QByteArray> roleNames() const;
43+ QByteArray profile() const;
44+ IndicatorsModel* model() const;
45+
46+ /* setters */
47+ void setModel(IndicatorsModel *model);
48+ void setProfile(const QByteArray& profile);
49+
50+ virtual QVariant data(const QModelIndex &index, int role) const;
51+
52+Q_SIGNALS:
53+ void totalCountChanged();
54+ void countChanged();
55+ void modelChanged();
56+ void profileChanged();
57+
58+private Q_SLOTS:
59+ void sourceRowsInserted(const QModelIndex &parent, int start, int end);
60+ void sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
61+ void sourceDataChanged(const QModelIndex& topRight, const QModelIndex& bottomRight);
62+
63+ void onActionStateUpdated();
64+
65+private:
66+ IndicatorsModel* m_model;
67+ QList<RootActionState*> m_rootActions;
68+ QList<bool> m_visible;
69+ QByteArray m_profile;
70+};
71+
72+#endif // VISIBLEINDICATORSMODEL_H