on xenial help sign in
Indicator visibility moved to VisibilityModel.
db61a4cNick Dedekind
Panel/IndicatorItem.qml−1
@@ -26,7 +26,6 @@ Item {
26 property bool highlighted: false
26 property bool highlighted: false
27 property bool dimmed: false
27 property bool dimmed: false
28 property var indicatorProperties: undefined
28 property var indicatorProperties: undefined
29− property bool indicatorVisible: loader.item != undefined && loader.status == Loader.Ready ? loader.item.enabled : false
30
29
31 opacity: dimmed ? 0.4 : 1
30 opacity: dimmed ? 0.4 : 1
32 Behavior on opacity { StandardAnimation {} }
31 Behavior on opacity { StandardAnimation {} }
Panel/IndicatorRow.qml+6−8
@@ -53,11 +53,16 @@ Item {
53 objectName: "rowRepeater"
53 objectName: "rowRepeater"
54 model: indicatorsModel ? indicatorsModel : undefined
54 model: indicatorsModel ? indicatorsModel : undefined
55
55
56+ onItemRemoved: {
57+ if (currentItemIndex == -1) {
58+ setDefaultItem(0);
59+ }
60+ }
61+
56 Item {
62 Item {
57 id: itemWrapper
63 id: itemWrapper
58 height: indicatorRow.height
64 height: indicatorRow.height
59 width: indicatorItem.width
65 width: indicatorItem.width
60− visible: indicatorItem.indicatorVisible
61
66
62 property int ownIndex: index
67 property int ownIndex: index
63 property alias highlighted: indicatorItem.highlighted
68 property alias highlighted: indicatorItem.highlighted
@@ -72,13 +77,6 @@ Item {
72
77
73 widgetSource: model.widgetSource
78 widgetSource: model.widgetSource
74 indicatorProperties : model.indicatorProperties
79 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− }
82 }
80 }
83
81
84 opacity: {
82 opacity: {
Panel/Indicators.qml+16−2
@@ -17,6 +17,8 @@
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19import Ubuntu.Gestures 0.1
19import Ubuntu.Gestures 0.1
20+import Unity.Indicators 0.1 as Indicators
21+import Utils 0.1
20
22
21import "../Components"
23import "../Components"
22import "../Components/ListItems"
24import "../Components/ListItems"
@@ -175,7 +177,7 @@ Showable {
175 top: indicatorRow.bottom
177 top: indicatorRow.bottom
176 bottom: handle.top
178 bottom: handle.top
177 }
179 }
178− indicatorsModel: indicatorsModel
180+ indicatorsModel: filteredIndicators
179 clip: !indicators.fullyOpened
181 clip: !indicators.fullyOpened
180 activeHeader: indicators.state == "hint" || indicators.state == "reveal"
182 activeHeader: indicators.state == "hint" || indicators.state == "reveal"
181
183
@@ -249,6 +251,18 @@ Showable {
249 id: indicatorsModel
251 id: indicatorsModel
250 }
252 }
251
253
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+
252 IndicatorRow {
266 IndicatorRow {
253 id: indicatorRow
267 id: indicatorRow
254 objectName: "indicatorRow"
268 objectName: "indicatorRow"
@@ -257,7 +271,7 @@ Showable {
257 right: parent.right
271 right: parent.right
258 }
272 }
259 height: indicators.panelHeight
273 height: indicators.panelHeight
260− indicatorsModel: indicatorsModel
274+ indicatorsModel: filteredIndicators
261 state: indicators.state
275 state: indicators.state
262
276
263 Connections {
277 Connections {
Panel/MenuContent.qml+6−18
@@ -17,7 +17,6 @@
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19import Unity.Indicators 0.1 as Indicators
19import Unity.Indicators 0.1 as Indicators
20−import Utils 0.1
21import "../Components"
20import "../Components"
22
21
23// FIXME : We dont want to use MainView.
22// FIXME : We dont want to use MainView.
@@ -28,7 +27,7 @@ MainView {
28
27
29 property QtObject indicatorsModel: null
28 property QtObject indicatorsModel: null
30 property bool __contentActive: false
29 property bool __contentActive: false
31− readonly property int currentMenuIndex : filteredIndicators.mapToSource(tabs.selectedTabIndex)
30+ readonly property int currentMenuIndex : tabs.selectedTabIndex
32 backgroundColor: "#221e1c" // FIXME not in palette yet
31 backgroundColor: "#221e1c" // FIXME not in palette yet
33 property int contentReleaseInterval: 20000
32 property int contentReleaseInterval: 20000
34 property bool activeHeader: false
33 property bool activeHeader: false
@@ -37,13 +36,11 @@ MainView {
37 height: units.gu(42)
36 height: units.gu(42)
38
37
39 function setCurrentMenuIndex(index) {
38 function setCurrentMenuIndex(index) {
40− var filteredIndex = filteredIndicators.mapFromSource(index)
41−
42− if (tabs.selectedTabIndex !== filteredIndex) {
39+ if (tabs.selectedTabIndex !== index) {
43 if (tabs.selectedTabIndex == -1) {
40 if (tabs.selectedTabIndex == -1) {
44 tabs.tabBar.animate = false;
41 tabs.tabBar.animate = false;
45 }
42 }
46− tabs.selectedTabIndex = filteredIndex;
43+ tabs.selectedTabIndex = index;
47 tabs.tabBar.animate = true;
44 tabs.tabBar.animate = true;
48 }
45 }
49 }
46 }
@@ -64,15 +61,6 @@ MainView {
64 tabs.tabBar.alwaysSelectionMode = activeHeader;
61 tabs.tabBar.alwaysSelectionMode = activeHeader;
65 }
62 }
66
63
67− SortFilterProxyModel {
68− id: filteredIndicators
69− model: indicatorsModel
70− dynamicSortFilter: true
71−
72− filterRole: Indicators.IndicatorsModelRole.IsVisible
73− filterRegExp: RegExp("^true$")
74− }
75−
76 Tabs {
64 Tabs {
77 id: tabs
65 id: tabs
78 objectName: "tabs"
66 objectName: "tabs"
@@ -81,8 +69,8 @@ MainView {
81
69
82 Repeater {
70 Repeater {
83 id: repeater
71 id: repeater
84− model: filteredIndicators
72+ model: indicatorsModel
85− objectName: "menus"
73+ objectName: "tabsRepeater"
86
74
87 // FIXME: This is needed because tabs dont handle repeaters well.
75 // FIXME: This is needed because tabs dont handle repeaters well.
88 // Due to the child ordering happening after child insertion.
76 // Due to the child ordering happening after child insertion.
@@ -126,7 +114,7 @@ MainView {
126 item[pName] = indicatorProperties[pName]
114 item[pName] = indicatorProperties[pName]
127 }
115 }
128 }
116 }
129− if (contentActive && menus.visible) {
117+ if (contentActive && tabs.visible) {
130 item.start()
118 item.start()
131 }
119 }
132 }
120 }
plugins/Unity/Indicators/CMakeLists.txt+2
@@ -24,6 +24,7 @@ include_directories(
24)
24)
25
25
26set(IndicatorsQML_SOURCES
26set(IndicatorsQML_SOURCES
27+ cachedunitymenumodel.cpp
27 indicator.cpp
28 indicator.cpp
28 indicators.h
29 indicators.h
29 indicatorsmanager.cpp
30 indicatorsmanager.cpp
@@ -34,6 +35,7 @@ set(IndicatorsQML_SOURCES
34 rootactionstate.cpp
35 rootactionstate.cpp
35 unitymenumodelcache.cpp
36 unitymenumodelcache.cpp
36 unitymenumodelstack.cpp
37 unitymenumodelstack.cpp
38+ visibleindicatorsmodel.cpp
37)
39)
38add_definitions(-DUNITYINDICATORS_LIBRARY)
40add_definitions(-DUNITYINDICATORS_LIBRARY)
39
41
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 @@
18 */
18 */
19
19
20#include "indicator.h"
20#include "indicator.h"
21+#include "cachedunitymenumodel.h"
21
22
22#include <QStringList>
23#include <QStringList>
24+#include <unitymenumodel.h>
23
25
24Indicator::Indicator(QObject *parent)
26Indicator::Indicator(QObject *parent)
25 : QObject(parent),
27 : QObject(parent),
26− m_position(0),
28+ m_position(0)
27− m_visible(false)
28{
29{
29}
30}
30
31
31Indicator::~Indicator()
32Indicator::~Indicator()
32{
33{
34+ qDeleteAll(m_cachedModels);
35+ m_cachedModels.clear();
33}
36}
34
37
35void Indicator::init(const QString& busName, const QSettings& settings)
38void Indicator::init(const QString& busName, const QSettings& settings)
@@ -87,21 +90,6 @@ void Indicator::setPosition(int position)
87 }
90 }
88}
91}
89
92
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−
105QVariant Indicator::indicatorProperties() const
93QVariant Indicator::indicatorProperties() const
106{
94{
107 return m_properties;
95 return m_properties;
@@ -115,3 +103,31 @@ void Indicator::setIndicatorProperties(const QVariant &properties)
115 Q_EMIT indicatorPropertiesChanged(m_properties);
103 Q_EMIT indicatorPropertiesChanged(m_properties);
116 }
104 }
117}
105}
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 @@
25
25
26#include <QObject>
26#include <QObject>
27#include <QSettings>
27#include <QSettings>
28+class QAbstractItemModel;
29+class CachedUnityMenuModel;
28
30
29class UNITYINDICATORS_EXPORT Indicator : public QObject
31class UNITYINDICATORS_EXPORT Indicator : public QObject
30{
32{
@@ -40,15 +42,12 @@ public:
40 QString identifier() const;
42 QString identifier() const;
41 int position() const;
43 int position() const;
42 QVariant indicatorProperties() const;
44 QVariant indicatorProperties() const;
43− bool isVisible() const;
44
45
45− // is set once we know if we're connected.
46+ QAbstractItemModel* getMenuModel(const QString& profile);
46− bool setVisible(bool visible);
47
47
48Q_SIGNALS:
48Q_SIGNALS:
49 void identifierChanged(const QString &identifier);
49 void identifierChanged(const QString &identifier);
50 void positionChanged(int position);
50 void positionChanged(int position);
51− void visibleChanged(bool visible);
52 void indicatorPropertiesChanged(const QVariant &properties);
51 void indicatorPropertiesChanged(const QVariant &properties);
53
52
54protected:
53protected:
@@ -59,8 +58,8 @@ protected:
59private:
58private:
60 QString m_identifier;
59 QString m_identifier;
61 int m_position;
60 int m_position;
62− bool m_visible;
63 QVariant m_properties;
61 QVariant m_properties;
62+ QHash<QString, CachedUnityMenuModel*> m_cachedModels;
64};
63};
65
64
66#endif // INDICATOR_H
65#endif // INDICATOR_H
plugins/Unity/Indicators/indicatorsmanager.cpp+4−7
@@ -214,14 +214,11 @@ void IndicatorsManager::unloadFile(const QFileInfo& file)
214 IndicatorData* data = iter.value();
214 IndicatorData* data = iter.value();
215 if (data->m_fileInfo.absoluteFilePath() == file.absoluteFilePath())
215 if (data->m_fileInfo.absoluteFilePath() == file.absoluteFilePath())
216 {
216 {
217− if (!data->m_verified)
218− {
219− QString name = data->m_name;
217+ QString name = data->m_name;
220− Q_EMIT indicatorAboutToBeUnloaded(name);
218+ Q_EMIT indicatorAboutToBeUnloaded(name);
221
219
222− delete data;
220+ delete data;
223− iter.remove();
221+ iter.remove();
224− }
225 }
222 }
226 }
223 }
227
224
plugins/Unity/Indicators/indicatorsmodel.cpp+16−31
@@ -229,9 +229,9 @@ QVariant IndicatorsModel::defaultData(Indicator::Ptr indicator, int role)
229 case IndicatorsModelRole::Description:
229 case IndicatorsModelRole::Description:
230 return "";
230 return "";
231 case IndicatorsModelRole::WidgetSource:
231 case IndicatorsModelRole::WidgetSource:
232− return shellAppDirectory()+"/Panel/Indicators/DefaultIndicatorWidget2.qml";
232+ return shellAppDirectory()+"/Panel/Indicators/DefaultIndicatorWidget.qml";
233 case IndicatorsModelRole::PageSource:
233 case IndicatorsModelRole::PageSource:
234− return shellAppDirectory()+"/Panel/Indicators/DefaultIndicatorPage2.qml";
234+ return shellAppDirectory()+"/Panel/Indicators/DefaultIndicatorPage.qml";
235 }
235 }
236 return QVariant();
236 return QVariant();
237}
237}
@@ -270,7 +270,7 @@ QVariant IndicatorsModel::data(const QModelIndex &index, int role) const
270 }
270 }
271 break;
271 break;
272 case IndicatorsModelRole::IsVisible:
272 case IndicatorsModelRole::IsVisible:
273− return (indicator ? indicator->isVisible() : false);
273+ return true;
274 case IndicatorsModelRole::Title:
274 case IndicatorsModelRole::Title:
275 case IndicatorsModelRole::Description:
275 case IndicatorsModelRole::Description:
276 case IndicatorsModelRole::WidgetSource:
276 case IndicatorsModelRole::WidgetSource:
@@ -282,34 +282,6 @@ QVariant IndicatorsModel::data(const QModelIndex &index, int role) const
282 return QVariant();
282 return QVariant();
283}
283}
284
284
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−
313QVariant IndicatorsModel::indicatorData(const Indicator::Ptr& indicator, int role) const
285QVariant IndicatorsModel::indicatorData(const Indicator::Ptr& indicator, int role) const
314{
286{
315 if (indicator && m_parsed_indicator_data.contains(indicator->identifier()))
287 if (indicator && m_parsed_indicator_data.contains(indicator->identifier()))
@@ -352,3 +324,16 @@ QVariant IndicatorsModel::indicatorData() const
352{
324{
353 return m_indicator_data;
325 return m_indicator_data;
354}
326}
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
37 Q_PROPERTY(QVariant indicatorData READ indicatorData WRITE setIndicatorData NOTIFY indicatorDataChanged)
37 Q_PROPERTY(QVariant indicatorData READ indicatorData WRITE setIndicatorData NOTIFY indicatorDataChanged)
38
38
39public:
39public:
40−
41 IndicatorsModel(QObject *parent=0);
40 IndicatorsModel(QObject *parent=0);
42 ~IndicatorsModel();
41 ~IndicatorsModel();
43
42
@@ -45,19 +44,18 @@ public:
45 Q_INVOKABLE void unload();
44 Q_INVOKABLE void unload();
46
45
47 Q_INVOKABLE QVariant data(int row, int role) const;
46 Q_INVOKABLE QVariant data(int row, int role) const;
48− Q_INVOKABLE void setData(int row, const QVariant& value, int role);
49
47
50 /* QAbstractItemModel */
48 /* QAbstractItemModel */
51 QHash<int, QByteArray> roleNames() const;
49 QHash<int, QByteArray> roleNames() const;
52 int columnCount(const QModelIndex &parent = QModelIndex()) const;
50 int columnCount(const QModelIndex &parent = QModelIndex()) const;
53 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
51 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
54− bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole);
55 QModelIndex parent (const QModelIndex &index) const;
52 QModelIndex parent (const QModelIndex &index) const;
56 int rowCount(const QModelIndex &parent = QModelIndex()) const;
53 int rowCount(const QModelIndex &parent = QModelIndex()) const;
57
54
58 void setIndicatorData(const QVariant& data);
55 void setIndicatorData(const QVariant& data);
59 QVariant indicatorData() const;
56 QVariant indicatorData() const;
60
57
58+ QAbstractItemModel* getMenuModelForIndexProfile(const QModelIndex& index, const QString& profile) const;
61
59
62Q_SIGNALS:
60Q_SIGNALS:
63 void countChanged();
61 void countChanged();
plugins/Unity/Indicators/plugin.cpp+5−1
@@ -32,21 +32,25 @@
32#include "rootactionstate.h"
32#include "rootactionstate.h"
33#include "unitymenumodelcache.h"
33#include "unitymenumodelcache.h"
34#include "unitymenumodelstack.h"
34#include "unitymenumodelstack.h"
35+#include "visibleindicatorsmodel.h"
36+#include "cachedunitymenumodel.h"
35
37
36static QObject* menuModelCacheSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
38static QObject* menuModelCacheSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
37 Q_UNUSED(engine);
39 Q_UNUSED(engine);
38 Q_UNUSED(scriptEngine);
40 Q_UNUSED(scriptEngine);
39− return new UnityMenuModelCache;
41+ return UnityMenuModelCache::cache();
40}
42}
41
43
42void Indicators2Plugin::registerTypes(const char *uri)
44void Indicators2Plugin::registerTypes(const char *uri)
43{
45{
44 qmlRegisterType<IndicatorsManager>(uri, 0, 1, "IndicatorsManager");
46 qmlRegisterType<IndicatorsManager>(uri, 0, 1, "IndicatorsManager");
45 qmlRegisterType<IndicatorsModel>(uri, 0, 1, "IndicatorsModel");
47 qmlRegisterType<IndicatorsModel>(uri, 0, 1, "IndicatorsModel");
48+ qmlRegisterType<VisibleIndicatorsModel>(uri, 0, 1, "VisibleIndicatorsModel");
46 qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
49 qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
47 qmlRegisterType<UnityMenuModelStack>(uri, 0, 1, "UnityMenuModelStack");
50 qmlRegisterType<UnityMenuModelStack>(uri, 0, 1, "UnityMenuModelStack");
48 qmlRegisterType<RootActionState>(uri, 0, 1, "RootActionState");
51 qmlRegisterType<RootActionState>(uri, 0, 1, "RootActionState");
49 qmlRegisterType<ModelPrinter>(uri, 0, 1, "ModelPrinter");
52 qmlRegisterType<ModelPrinter>(uri, 0, 1, "ModelPrinter");
53+ qmlRegisterType<CachedUnityMenuModel>(uri, 0, 1, "CachedUnityMenuModel");
50
54
51 qmlRegisterSingletonType<UnityMenuModelCache>(uri, 0, 1, "UnityMenuModelCache", menuModelCacheSingleton);
55 qmlRegisterSingletonType<UnityMenuModelCache>(uri, 0, 1, "UnityMenuModelCache", menuModelCacheSingleton);
52
56
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 {
39
39
40 property alias menuModel: cachedModel.model
40 property alias menuModel: cachedModel.model
41
41
42− CachedUnityMenuModel {
42+ Indicators.CachedUnityMenuModel {
43 id: cachedModel
43 id: cachedModel
44− busName: active ? indicatorItem.busName : ""
44+ busName: indicatorItem.busName
45− actionsObjectPath: active ? indicatorItem.actionsObjectPath : ""
45+ actions: { "indicator": indicatorItem.actionsObjectPath }
46 menuObjectPath: active ? indicatorItem.deviceMenuObjectPath : ""
46 menuObjectPath: active ? indicatorItem.deviceMenuObjectPath : ""
47 }
47 }
48}
48}
plugins/Unity/Indicators/qml/qmldir−1
@@ -4,7 +4,6 @@ typeinfo plugin.qmltypes
4
4
5BaseMenuItem 0.1 BaseMenuItem.qml
5BaseMenuItem 0.1 BaseMenuItem.qml
6ButtonMenuItem 0.1 ButtonMenuItem.qml
6ButtonMenuItem 0.1 ButtonMenuItem.qml
7−CachedUnityMenuModel 0.1 CachedUnityMenuModel.qml
8DivMenuItem 0.1 DivMenuItem.qml
7DivMenuItem 0.1 DivMenuItem.qml
9FramedMenuItem 0.1 FramedMenuItem.qml
8FramedMenuItem 0.1 FramedMenuItem.qml
10HLine 0.1 HLine.qml
9HLine 0.1 HLine.qml
plugins/Unity/Indicators/rootactionstate.cpp+14−10
@@ -31,7 +31,7 @@ extern "C" {
31
31
32RootActionState::RootActionState(QObject *parent)
32RootActionState::RootActionState(QObject *parent)
33 : ActionStateParser(parent),
33 : ActionStateParser(parent),
34− m_menu(NULL)
34+ m_manageParserParent(false)
35{
35{
36}
36}
37
37
@@ -47,18 +47,17 @@ UnityMenuModel* RootActionState::menu() const
47void RootActionState::setMenu(UnityMenuModel* menu)
47void RootActionState::setMenu(UnityMenuModel* menu)
48{
48{
49 if (m_menu != menu) {
49 if (m_menu != menu) {
50− if (m_menu) {
50+ if (!m_menu.isNull()) {
51 m_menu->disconnect(this);
51 m_menu->disconnect(this);
52 }
52 }
53 m_menu = menu;
53 m_menu = menu;
54
54
55− if (m_menu) {
55+ if (menu) {
56− connect(m_menu, SIGNAL(rowsInserted(const QModelIndex&, int, int)), SLOT(onModelRowsAdded(const QModelIndex&, int, int)));
56+ connect(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)));
57+ connect(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>&)));
58+ connect(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);
61 }
59 }
60+
62 updateActionState();
61 updateActionState();
63 Q_EMIT menuChanged();
62 Q_EMIT menuChanged();
64 }
63 }
@@ -94,8 +93,13 @@ void RootActionState::onModelDataChanged(const QModelIndex& topLeft, const QMode
94
93
95void RootActionState::updateActionState()
94void RootActionState::updateActionState()
96{
95{
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+
98 m_cachedState = m_menu->get(0, "actionState").toMap();
100 m_cachedState = m_menu->get(0, "actionState").toMap();
101+
102+ m_menu->setActionStateParser(oldParser);
99 } else {
103 } else {
100 m_cachedState.clear();
104 m_cachedState.clear();
101 }
105 }
@@ -105,7 +109,7 @@ void RootActionState::updateActionState()
105
109
106bool RootActionState::isValid() const
110bool RootActionState::isValid() const
107{
111{
108− return m_menu && m_menu->rowCount() > 0;
112+ return !m_menu.isNull() && m_menu->rowCount() > 0;
109}
113}
110
114
111QString RootActionState::label() const
115QString RootActionState::label() const
plugins/Unity/Indicators/rootactionstate.h+3−1
@@ -23,6 +23,7 @@
23#include "unityindicatorsglobal.h"
23#include "unityindicatorsglobal.h"
24
24
25#include <actionstateparser.h>
25#include <actionstateparser.h>
26+#include <QPointer>
26
27
27class UnityMenuModel;
28class UnityMenuModel;
28
29
@@ -75,8 +76,9 @@ private Q_SLOTS:
75private:
76private:
76 void updateActionState();
77 void updateActionState();
77
78
78− UnityMenuModel* m_menu;
79+ QPointer<UnityMenuModel> m_menu;
79 QVariantMap m_cachedState;
80 QVariantMap m_cachedState;
81+ bool m_manageParserParent;
80};
82};
81
83
82#endif // ROOTACTIONSTATE_H
84#endif // ROOTACTIONSTATE_H
plugins/Unity/Indicators/unitymenumodelcache.cpp+7−1
@@ -39,4 +39,10 @@ void UnityMenuModelCache::registerModel(const QString& path, UnityMenuModel* men
39{
39{
40 menuModel->setParent(this);
40 menuModel->setParent(this);
41 m_menuModels[path] = menuModel;
41 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:
37 Q_INVOKABLE UnityMenuModel* model(const QString& path) const;
37 Q_INVOKABLE UnityMenuModel* model(const QString& path) const;
38 Q_INVOKABLE void registerModel(const QString& path, UnityMenuModel* menuModel);
38 Q_INVOKABLE void registerModel(const QString& path, UnityMenuModel* menuModel);
39
39
40+ static UnityMenuModelCache* cache();
41+
40private:
42private:
41 QHash<QString, UnityMenuModel*> m_menuModels;
43 QHash<QString, UnityMenuModel*> m_menuModels;
42};
44};
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