18#include "qlimitproxymodelqml.h"
23QLimitProxyModelQML::QLimitProxyModelQML(QObject *parent)
24 : QIdentityProxyModel(parent)
26 , m_sourceInserting(false)
27 , m_sourceRemoving(false)
28 , m_dataChangedBegin(-1)
29 , m_dataChangedEnd(-1)
31 connect(
this, &QLimitProxyModelQML::modelReset,
this, &QLimitProxyModelQML::countChanged);
32 connect(
this, &QLimitProxyModelQML::rowsInserted,
this, &QLimitProxyModelQML::countChanged);
33 connect(
this, &QLimitProxyModelQML::rowsRemoved,
this, &QLimitProxyModelQML::countChanged);
36QHash<int, QByteArray> QLimitProxyModelQML::roleNames()
const
38 return sourceModel() ? sourceModel()->roleNames() : QHash<int, QByteArray>();
42QLimitProxyModelQML::setModel(QAbstractItemModel *itemModel)
44 if (itemModel != sourceModel()) {
45 if (sourceModel() !=
nullptr) {
46 sourceModel()->disconnect(
this);
49 setSourceModel(itemModel);
51 if (sourceModel() !=
nullptr) {
53 disconnect(sourceModel(), &QAbstractItemModel::rowsAboutToBeInserted,
this,
nullptr);
54 disconnect(sourceModel(), &QAbstractItemModel::rowsInserted,
this,
nullptr);
55 disconnect(sourceModel(), &QAbstractItemModel::rowsAboutToBeRemoved,
this,
nullptr);
56 disconnect(sourceModel(), &QAbstractItemModel::rowsRemoved,
this,
nullptr);
59 connect(sourceModel(), &QAbstractItemModel::rowsAboutToBeInserted,
60 this, &QLimitProxyModelQML::sourceRowsAboutToBeInserted);
61 connect(sourceModel(), &QAbstractItemModel::rowsInserted,
62 this, &QLimitProxyModelQML::sourceRowsInserted);
63 connect(sourceModel(), &QAbstractItemModel::rowsAboutToBeRemoved,
64 this, &QLimitProxyModelQML::sourceRowsAboutToBeRemoved);
65 connect(sourceModel(), &QAbstractItemModel::rowsRemoved,
66 this, &QLimitProxyModelQML::sourceRowsRemoved);
68 Q_EMIT modelChanged();
73QLimitProxyModelQML::rowCount(
const QModelIndex &parent)
const
78 const int unlimitedCount = QIdentityProxyModel::rowCount(parent);
79 return m_limit < 0 ? unlimitedCount : qMin(m_limit, unlimitedCount);
83QLimitProxyModelQML::limit()
const
89QLimitProxyModelQML::setLimit(
int limit)
91 if (limit != m_limit) {
92 bool inserting =
false;
93 bool removing =
false;
94 const int oldCount = rowCount();
95 const int unlimitedCount = QIdentityProxyModel::rowCount();
97 if (limit < oldCount) {
99 beginRemoveRows(QModelIndex(), limit, oldCount - 1);
101 }
else if (limit < 0) {
102 if (m_limit < unlimitedCount) {
104 beginInsertRows(QModelIndex(), m_limit, unlimitedCount - 1);
107 if (limit > m_limit && unlimitedCount > m_limit) {
109 beginInsertRows(QModelIndex(), m_limit, qMin(limit, unlimitedCount) - 1);
110 }
else if (limit < m_limit && limit < oldCount) {
112 beginRemoveRows(QModelIndex(), limit, oldCount - 1);
120 }
else if (removing) {
124 Q_EMIT limitChanged();
129QLimitProxyModelQML::sourceRowsAboutToBeInserted(
const QModelIndex &parent,
int start,
int end)
132 beginInsertRows(mapFromSource(parent), start, end);
133 m_sourceInserting =
true;
134 }
else if (start < m_limit) {
135 const int nSourceAddedItems = end - start + 1;
136 const int currentCount = QIdentityProxyModel::rowCount();
137 if (currentCount + nSourceAddedItems <= m_limit) {
140 beginInsertRows(mapFromSource(parent), start, end);
141 m_sourceInserting =
true;
142 }
else if (currentCount >= m_limit) {
150 m_dataChangedBegin = start;
151 m_dataChangedEnd = m_limit - 1;
162 const int nItemsToInsert = m_limit - currentCount;
163 beginInsertRows(mapFromSource(parent), start, start + nItemsToInsert - 1);
164 m_sourceInserting =
true;
165 m_dataChangedBegin = start + nItemsToInsert;
166 m_dataChangedEnd = m_limit - 1;
167 if (m_dataChangedBegin > m_dataChangedEnd) {
170 m_dataChangedBegin = -1;
171 m_dataChangedEnd = -1;
178QLimitProxyModelQML::sourceRowsAboutToBeRemoved(
const QModelIndex &parent,
int start,
int end)
181 beginRemoveRows(mapFromSource(parent), start, end);
182 m_sourceRemoving =
true;
183 }
else if (start < m_limit) {
184 const int nSourceRemovedItems = end - start + 1;
185 const int currentCount = QIdentityProxyModel::rowCount();
186 if (currentCount <= m_limit) {
189 beginRemoveRows(mapFromSource(parent), start, end);
190 m_sourceRemoving =
true;
191 }
else if (currentCount - nSourceRemovedItems >= m_limit) {
201 m_dataChangedBegin = start;
202 m_dataChangedEnd = m_limit - 1;
213 const int nItemsToRemove = m_limit - (currentCount - nSourceRemovedItems);
214 beginRemoveRows(mapFromSource(parent), m_limit - nItemsToRemove, m_limit - 1);
215 m_sourceRemoving =
true;
216 m_dataChangedBegin = start;
217 m_dataChangedEnd = m_limit - nItemsToRemove - 1;
218 if (m_dataChangedBegin > m_dataChangedEnd) {
219 m_dataChangedBegin = -1;
220 m_dataChangedEnd = -1;
227QLimitProxyModelQML::sourceRowsInserted(
const QModelIndex & ,
int ,
int )
229 if (m_sourceInserting) {
231 m_sourceInserting =
false;
233 if (m_dataChangedBegin != -1 && m_dataChangedEnd != -1) {
234 dataChanged(index(m_dataChangedBegin, 0), index(m_dataChangedEnd, 0));
235 m_dataChangedBegin = -1;
236 m_dataChangedEnd = -1;
241QLimitProxyModelQML::sourceRowsRemoved(
const QModelIndex & ,
int ,
int )
243 if (m_sourceRemoving) {
245 m_sourceRemoving =
false;
247 if (m_dataChangedBegin != -1 && m_dataChangedEnd != -1) {
248 dataChanged(index(m_dataChangedBegin, 0), index(m_dataChangedEnd, 0));
249 m_dataChangedBegin = -1;
250 m_dataChangedEnd = -1;