on dd024c8 help sign in
unity8/plugins/Utils/qlimitproxymodelqml.cpp
166 lines 5.5 kB history raw
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 */
17// self
18#include "qlimitproxymodelqml.h"
20// Qt
21#include <QDebug>
23QLimitProxyModelQML::QLimitProxyModelQML(QObject *parent)
24 : QIdentityProxyModel(parent)
25 , m_limit(-1)
26 , m_sourceInserting(false)
27 , m_sourceRemoving(false)
29 connect(this, SIGNAL(modelReset()), SIGNAL(countChanged()));
30 connect(this, SIGNAL(rowsInserted(QModelIndex,int,int)), SIGNAL(countChanged()));
31 connect(this, SIGNAL(rowsRemoved(QModelIndex,int,int)), SIGNAL(countChanged()));
34QHash<int, QByteArray> QLimitProxyModelQML::roleNames() const
36 return sourceModel() ? sourceModel()->roleNames() : QHash<int, QByteArray>();
39void
40QLimitProxyModelQML::setModel(QAbstractItemModel *itemModel)
42 if (itemModel != sourceModel()) {
43 if (sourceModel() != NULL) {
44 sourceModel()->disconnect(this);
45 }
47 setSourceModel(itemModel);
49 if (sourceModel() != NULL) {
50 // Disconnect the QIdentityProxyModel handling for rows removed/added...
51 disconnect(sourceModel(), SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), this, NULL);
52 disconnect(sourceModel(), SIGNAL(rowsInserted(QModelIndex,int,int)), this, NULL);
53 disconnect(sourceModel(), SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), this, NULL);
54 disconnect(sourceModel(), SIGNAL(rowsRemoved(QModelIndex,int,int)), this, NULL);
56 // ... and use our own
57 connect(sourceModel(), SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
58 this, SLOT(sourceRowsAboutToBeInserted(QModelIndex,int,int)));
59 connect(sourceModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
60 this, SLOT(sourceRowsInserted(QModelIndex,int,int)));
61 connect(sourceModel(), SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
62 this, SLOT(sourceRowsAboutToBeRemoved(QModelIndex,int,int)));
63 connect(sourceModel(), SIGNAL(rowsRemoved(QModelIndex,int,int)),
64 this, SLOT(sourceRowsRemoved(QModelIndex,int,int)));
65 }
66 Q_EMIT modelChanged();
67 }
70int
71QLimitProxyModelQML::rowCount(const QModelIndex &parent) const
73 if (parent.isValid()) // We are not a tree
74 return 0;
76 const int unlimitedCount = QIdentityProxyModel::rowCount(parent);
77 return m_limit < 0 ? unlimitedCount : qMin(m_limit, unlimitedCount);
80int
81QLimitProxyModelQML::limit() const
83 return m_limit;
86void
87QLimitProxyModelQML::setLimit(int limit)
89 if (limit != m_limit) {
90 bool inserting = false;
91 bool removing = false;
92 const int oldCount = rowCount();
93 const int unlimitedCount = QIdentityProxyModel::rowCount();
94 if (m_limit < 0) {
95 if (limit < oldCount) {
96 removing = true;
97 beginRemoveRows(QModelIndex(), limit, oldCount - 1);
98 }
99 } else if (limit < 0) {
100 if (m_limit < unlimitedCount) {
101 inserting = true;
102 beginInsertRows(QModelIndex(), m_limit, unlimitedCount - 1);
103 }
104 } else {
105 if (limit > m_limit && unlimitedCount > m_limit) {
106 inserting = true;
107 beginInsertRows(QModelIndex(), m_limit, qMin(limit, unlimitedCount) - 1);
108 } else if (limit < m_limit && limit < oldCount) {
109 removing = true;
110 beginRemoveRows(QModelIndex(), limit, oldCount - 1);
111 }
112 }
114 m_limit = limit;
116 if (inserting) {
117 endInsertRows();
118 } else if (removing) {
119 endRemoveRows();
120 }
122 Q_EMIT limitChanged();
123 }
126void
127QLimitProxyModelQML::sourceRowsAboutToBeInserted(const QModelIndex &parent, int start, int end)
129 if (m_limit < 0) {
130 beginInsertRows(mapFromSource(parent), start, end);
131 m_sourceInserting = true;
132 } else if (start < m_limit) {
133 beginInsertRows(mapFromSource(parent), start, qMin(m_limit - 1, end));
134 m_sourceInserting = true;
135 }
138void
139QLimitProxyModelQML::sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
141 if (m_limit < 0) {
142 beginRemoveRows(mapFromSource(parent), start, end);
143 m_sourceRemoving = true;
144 } else if (start < m_limit) {
145 beginRemoveRows(mapFromSource(parent), start, qMin(m_limit - 1, end));
146 m_sourceRemoving = true;
147 }
150void
151QLimitProxyModelQML::sourceRowsInserted(const QModelIndex & /*parent*/, int /*start*/, int /*end*/)
153 if (m_sourceInserting) {
154 endInsertRows();
155 m_sourceInserting = false;
156 }
159void
160QLimitProxyModelQML::sourceRowsRemoved(const QModelIndex & /*parent*/, int /*start*/, int /*end*/)
162 if (m_sourceRemoving) {
163 endRemoveRows();
164 m_sourceRemoving = false;
165 }