on eaecfc2 help sign in
unity8/plugins/Unity/Indicators/indicatorsmodel.cpp
271 lines 7.1 kB history raw
1/*
2 * Copyright 2012 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 * Renato Araujo Oliveira Filho <renato@canonical.com>
18 */
20#include "indicatorsmodel.h"
21#include "indicatorsmanager.h"
22#include "indicator.h"
23#include "indicators.h"
25#include <paths.h>
27#include <QQmlContext>
28#include <QQmlEngine>
29#include <QDebug>
31/*!
32 \qmltype IndicatorsModel
33 \inherits QAbstractListModel
35 \brief The IndicatorsModel class defines the list model for indicators
37 \b {This component is under heavy development.}
39 This class expose the available indicators.
41 \code
42 IndicatorsModel {
43 id: menuModel
44 }
46 ListView {
47 id: view
48 model: menuModel
49 Component.onCompleted: menuModel.load()
50 }
51 \endcode
52*/
53IndicatorsModel::IndicatorsModel(QObject *parent)
54 : QAbstractListModel(parent)
56 m_manager = new IndicatorsManager(this);
57 QObject::connect(m_manager, SIGNAL(indicatorLoaded(const QString&)), this, SLOT(onIndicatorLoaded(const QString&)));
58 QObject::connect(m_manager, SIGNAL(indicatorAboutToBeUnloaded(const QString&)), this, SLOT(onIndicatorAboutToBeUnloaded(const QString&)));
60 QObject::connect(this, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SIGNAL(countChanged()));
61 QObject::connect(this, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SIGNAL(countChanged()));
62 QObject::connect(this, SIGNAL(modelReset()), this, SIGNAL(countChanged()));
65/*! \internal */
66IndicatorsModel::~IndicatorsModel()
68 disconnect(m_manager, 0, 0, 0);
69 m_manager->deleteLater();
72/*!
73 \qmlproperty IndicatorsModel::count
74 The number of data entries in the model.
76 \b Note: methods should only be called after the Component has completed.
77*/
78int IndicatorsModel::count() const
80 return rowCount();
83/*!
84 \qmlmethod IndicatorsModel::unload()
86 Load all indicators.
87*/
88void IndicatorsModel::load(const QString& profile)
90 m_indicators.clear();
91 m_manager->load(profile);
94/*!
95 \qmlmethod IndicatorsModel::unload()
97 Unload all indicators.
98*/
99void IndicatorsModel::unload()
101 m_manager->unload();
104/*! \internal */
105void IndicatorsModel::onIndicatorLoaded(const QString& indicator_name)
107 Indicator::Ptr indicator = m_manager->indicator(indicator_name);
108 if (!indicator)
109 {
110 return;
111 }
113 if (m_indicators.indexOf(indicator) >= 0)
114 {
115 return;
116 }
118 // find the insert position
119 int pos = 0;
120 while (pos < count())
121 {
122 // keep going while the existing position is greater. (put lower position on end)
123 if (indicator->position() >= data(index(pos), IndicatorsModelRole::Position).toInt())
124 break;
125 pos++;
126 }
128 QObject::connect(indicator.data(), SIGNAL(identifierChanged(const QString&)), this, SLOT(onIdentifierChanged()));
129 QObject::connect(indicator.data(), SIGNAL(indicatorPropertiesChanged(const QVariant&)), this, SLOT(onIndicatorPropertiesChanged()));
131 beginInsertRows(QModelIndex(), pos, pos);
133 m_indicators.insert(pos, indicator);
134 endInsertRows();
137/*! \internal */
138void IndicatorsModel::onIndicatorAboutToBeUnloaded(const QString& indicator_name)
140 Indicator::Ptr indicator = m_manager->indicator(indicator_name);
141 if (!indicator)
142 {
143 return;
144 }
146 int i = 0;
147 QMutableListIterator<Indicator::Ptr> iter(m_indicators);
148 while(iter.hasNext())
149 {
150 if (indicator == iter.next())
151 {
152 beginRemoveRows(QModelIndex(), i, i);
153 iter.remove();
154 endRemoveRows();
155 break;
156 }
157 i++;
158 }
162/*! \internal */
163void IndicatorsModel::onIdentifierChanged()
165 notifyDataChanged(QObject::sender(), IndicatorsModelRole::Identifier);
168/*! \internal */
169void IndicatorsModel::onIndicatorPropertiesChanged()
171 notifyDataChanged(QObject::sender(), IndicatorsModelRole::IndicatorProperties);
174/*! \internal */
175void IndicatorsModel::notifyDataChanged(QObject *sender, int role)
177 Indicator* indicator = qobject_cast<Indicator*>(sender);
178 if (!indicator)
179 {
180 return;
181 }
183 int index = 0;
184 QMutableListIterator<Indicator::Ptr> iter(m_indicators);
185 while(iter.hasNext())
186 {
187 if (indicator == iter.next())
188 {
189 QModelIndex changedIndex = this->index(index);
190 dataChanged(changedIndex, changedIndex, QVector<int>() << role);
191 break;
192 }
193 index++;
194 }
197/*! \internal */
198QHash<int, QByteArray> IndicatorsModel::roleNames() const
200 static QHash<int, QByteArray> roles;
201 if (roles.isEmpty())
202 {
203 roles[IndicatorsModelRole::Identifier] = "identifier";
204 roles[IndicatorsModelRole::Position] = "position";
205 roles[IndicatorsModelRole::WidgetSource] = "widgetSource";
206 roles[IndicatorsModelRole::PageSource] = "pageSource";
207 roles[IndicatorsModelRole::IndicatorProperties] = "indicatorProperties";
208 }
209 return roles;
212/*! \internal */
213int IndicatorsModel::columnCount(const QModelIndex &) const
215 return 1;
218Q_INVOKABLE QVariant IndicatorsModel::data(int row, int role) const
220 return data(index(row, 0), role);
223/*! \internal */
224QVariant IndicatorsModel::data(const QModelIndex &index, int role) const
226 if (!index.isValid() || index.row() >= m_indicators.size())
227 return QVariant();
229 Indicator::Ptr indicator = m_indicators[index.row()];
231 switch (role)
232 {
233 case IndicatorsModelRole::Identifier:
234 if (indicator)
235 {
236 return QVariant(indicator->identifier());
237 }
238 break;
239 case IndicatorsModelRole::Position:
240 if (indicator)
241 {
242 return QVariant(indicator->position());
243 }
244 break;
245 case IndicatorsModelRole::IndicatorProperties:
246 if (indicator)
247 {
248 return QVariant(indicator->indicatorProperties());
249 }
250 break;
251 case IndicatorsModelRole::WidgetSource:
252 return qmlDirectory()+"/Panel/Indicators/DefaultIndicatorWidget.qml";
253 case IndicatorsModelRole::PageSource:
254 return qmlDirectory()+"/Panel/Indicators/DefaultIndicatorPage.qml";
255 default:
256 break;
257 }
258 return QVariant();
261/*! \internal */
262QModelIndex IndicatorsModel::parent(const QModelIndex&) const
264 return QModelIndex();
267/*! \internal */
268int IndicatorsModel::rowCount(const QModelIndex&) const
270 return m_indicators.count();