@@ -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+}