on 5cf367a help sign in
unity8/plugins/Unity/Indicators/flatmenuproxymodel.cpp
285 lines 7.5 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 */
20extern "C" {
21#include <gio/gio.h>
24#include "flatmenuproxymodel.h"
25#include <QString>
26#include <QStringList>
28FlatMenuProxyModel::FlatMenuProxyModel(QAbstractItemModel *source)
29 : QAbstractProxyModel(source),
30 m_rowCount(0)
32 m_model = new QDBusMenuModel;
33 setSourceModel(m_model);
36/*! \internal */
37FlatMenuProxyModel::~FlatMenuProxyModel()
39 delete m_model;
42void FlatMenuProxyModel::setSourceModel(QAbstractItemModel *source)
44 if (sourceModel()) {
45 QAbstractItemModel *oldSource = sourceModel();
46 if (oldSource == source) {
47 return;
48 }
50 oldSource->disconnect(this);
51 }
53 QAbstractProxyModel::setSourceModel(source);
55 if (source) {
57 // FIXME - not working correctly with dynamic inserts/removes
59 connect(source,
60 SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
61 SLOT(onModelAboutToBeReset()));
62 connect(source,
63 SIGNAL(rowsInserted(QModelIndex,int,int)),
64 SLOT(onModelReset()));
66 connect(source,
67 SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
68 SLOT(onModelAboutToBeReset()));
69 connect(source,
70 SIGNAL(rowsRemoved(QModelIndex,int,int)),
71 SLOT(onModelReset()));
73 connect(source,
74 SIGNAL(modelAboutToBeReset()),
75 SLOT(onModelAboutToBeReset()));
76 connect(source,
77 SIGNAL(modelReset()),
78 SLOT(onModelReset()));
80 //Connection args
81 connect(source,
82 SIGNAL(busTypeChanged(DBusEnums::BusType)),
83 SIGNAL(busTypeChanged()));
85 connect(source,
86 SIGNAL(busNameChanged(const QString&)),
87 SIGNAL(busNameChanged()));
89 connect(source,
90 SIGNAL(objectPathChanged(const QString&)),
91 SIGNAL(objectPathChanged()));
93 connect(source,
94 SIGNAL(statusChanged(DBusEnums::ConnectionStatus)),
95 SIGNAL(statusChanged()));
97 // initiliaze rowCount
98 QModelIndex lastItem = source->index(source->rowCount() - 1, 0);
99 m_rowCount = recursiveRowCount(lastItem);
100 } else {
101 m_rowCount = 0;
102 }
104 Q_EMIT countChanged();
107void FlatMenuProxyModel::setBusName(const QString &busName)
109 m_model->setBusName(busName);
112QString FlatMenuProxyModel::busName() const
114 return m_model->busName();
117void FlatMenuProxyModel::setObjectPath(const QString &busPath)
119 m_model->setObjectPath(busPath);
122QString FlatMenuProxyModel::objectPath() const
124 return m_model->objectPath();
127int FlatMenuProxyModel::status() const
129 return m_model->status();
132DBusEnums::BusType FlatMenuProxyModel::busType() const
134 return m_model->busType();
137void FlatMenuProxyModel::setIntBusType(int type)
139 m_model->setBusType((DBusEnums::BusType) type);
142void FlatMenuProxyModel::start()
144 m_model->start();
147void FlatMenuProxyModel::stop()
149 m_model->stop();
152QModelIndex FlatMenuProxyModel::mapFromSource(const QModelIndex &index) const
154 if (!index.isValid()) {
155 return QModelIndex();
156 }
158 QModelIndex result = createIndex(rowOffsetOf(index, index.row()), 0);
159 return result;
162QModelIndex FlatMenuProxyModel::mapToSource(const QModelIndex &index) const
164 if (sourceModel() && m_indexCache.contains(index.row())) {
165 QString key = m_indexCache.value(index.row());
166 QStringList sections = key.split('.', QString::SkipEmptyParts);
167 QModelIndex sourceIndex = QModelIndex();
168 for(int i=0; i < sections.size(); i++) {
169 sourceIndex = sourceModel()->index(sections.at(i).toInt(), 9, sourceIndex);
170 }
171 return sourceIndex;
172 } else {
173 return QModelIndex();
174 }
177QModelIndex FlatMenuProxyModel::index(int row, int sectionRow, const QModelIndex &parent, const QString &key) const
179 for (int i = 0, count = 0; i < sourceModel()->rowCount(parent); i++) {
180 QModelIndex sourceIndex = sourceModel()->index(i, 0, parent);
181 int indexCount = recursiveRowCount(sourceIndex);
183 if (count == sectionRow) {
184 QString sectionKey = key + "." + QString::number(i);
185 m_indexCache.insert(row, sectionKey);
186 return createIndex(row, 0);
187 } else if ((count + indexCount) >= sectionRow) {
188 count++;
189 return index(row, sectionRow - count, sourceIndex, key + "." + QString::number(i));
190 }
192 count += indexCount + 1;
193 }
194 return QModelIndex();
197QModelIndex FlatMenuProxyModel::index(int row, int, const QModelIndex &) const
199 return index(row, row, QModelIndex(), "");
202QModelIndex FlatMenuProxyModel::parent(const QModelIndex &) const
204 return QModelIndex();
207int FlatMenuProxyModel::columnCount(const QModelIndex &) const
209 return 1;
212int FlatMenuProxyModel::rowCount(const QModelIndex &) const
214 return m_rowCount;
217int FlatMenuProxyModel::count() const
219 return rowCount(QModelIndex());
222void FlatMenuProxyModel::onModelAboutToBeReset()
224 beginResetModel();
227void FlatMenuProxyModel::onModelReset()
229 // initiliaze rowCount
230 m_rowCount = 0;
231 for (int i = 0, iMax = sourceModel()->rowCount(); i < iMax; i++) {
232 QModelIndex index = sourceModel()->index(i, 0);
233 m_rowCount += recursiveRowCount(index) + 1;
234 }
235 m_indexCache.clear();
236 endResetModel();
237 Q_EMIT countChanged();
240int FlatMenuProxyModel::recursiveRowCount(const QModelIndex &index) const
242 int size = sourceModel()->rowCount(index);
243 for (int i=0, iMax=size; i < iMax; i++) {
244 QModelIndex currentIndex = sourceModel()->index(i, 0, index);
245 size += recursiveRowCount(currentIndex);
246 }
248 return size;
251int FlatMenuProxyModel::rowOffsetOf(const QModelIndex &index, int row, bool inclusive) const
253 int offset = 0;
255 QModelIndex parent = index.parent();
257 // Check row 0 offset
258 while(parent.isValid()) {
259 offset += 1;
260 for (int i = 0; i < parent.row(); i++) {
261 QModelIndex currentIndex = sourceModel()->index(i, 0, parent);
262 offset += recursiveRowCount(currentIndex) + 1;
263 }
264 parent = parent.parent();
265 }
267 // Check index.row() offset
268 for(int i = 0; i < row; i++) {
269 QModelIndex currentIndex = sourceModel()->index(i, 0, index.parent());
270 offset += recursiveRowCount(currentIndex) + 1;
271 }
273 if (inclusive) {
274 // itself
275 QModelIndex currentIndex = sourceModel()->index(row, 0, index.parent());
276 offset += recursiveRowCount(currentIndex);
277 }
279 return offset;
282QVariant FlatMenuProxyModel::data(int row, int role) const
284 return QAbstractProxyModel::data(index(row, 0), role);