MauiKit Controls

mauimodel.cpp
1/*
2 * <one line to give the program's name and a brief idea of what it does.>
3 * Copyright (C) 2019 camilo <chiguitar@unal.edu.co>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include "mauimodel.h"
20#include "mauilist.h"
21#include <QDebug>
22#include <QDateTime>
23#include <QRegularExpression>
24
25MauiModel::MauiModel(QObject *parent)
26 : QSortFilterProxyModel(parent)
27 , m_model(new PrivateAbstractListModel(this))
28{
29
30}
31
32QVariantMap MauiModel::get(const int &index) const
33{
34 QVariantMap res;
35 if (index >= this->rowCount() || index < 0)
36 return res;
37
38 const auto roleNames = this->roleNames();
39 for (const auto &role : roleNames)
40 res.insert(role, this->index(index, 0).data(FMH::MODEL_NAME_KEY[role]).toString());
41
42 return res;
43}
44
45QVariantList MauiModel::getAll() const
46{
47 QVariantList res;
48 for (auto i = 0; i < this->rowCount(); i++)
49 res << this->get(i);
50
51 return res;
52}
53
54void MauiModel::setFilter(const QString &filter)
55{
56 if (this->m_filter == filter)
57 return;
58
59
60 this->m_filter = filter;
61 this->setFilterRegularExpression(this->m_filter);
62 Q_EMIT this->filterChanged(this->m_filter);
63 qDebug() << "Setting model filter" << m_filter;
64
65}
66
67const QString MauiModel::getFilter() const
68{
69 return this->m_filter;
70}
71
72void MauiModel::setFilters(const QStringList& filters)
73{
74 if (this->m_filters == filters)
75 return;
76
77 this->m_filters = filters;
78 QString rx;
79 for( int i = 0; i < m_filters.count(); ++i )
80 {
82 if( i > 0 )
83 rx += '|';
84 rx += filter;
85 }
86 qDebug() << "FILTERS" << filters << m_filters << m_filter << rx << filterCaseSensitivity() << ( filterCaseSensitivity() == Qt::CaseSensitivity::CaseSensitive);
87 QRegularExpression reg(rx, filterCaseSensitivity() == Qt::CaseSensitivity::CaseInsensitive ? QRegularExpression::CaseInsensitiveOption : QRegularExpression::NoPatternOption);
88// reg.setCaseSensitivity(filterCaseSensitivity());
90 Q_EMIT this->filtersChanged(this->m_filters);
91}
92
93const QStringList MauiModel::getFilters() const
94{
95 return m_filters;
96}
97
99{
100 this->m_filter.clear();
101 this->m_filters.clear();
102 this->setFilterFixedString("");
104 this->invalidateFilter();
105 Q_EMIT this->filtersChanged(this->m_filters);
106 Q_EMIT this->filterChanged(this->m_filter);
107
108}
109
110void MauiModel::PrivateAbstractListModel::reset()
111{
112 this->beginResetModel();
113 this->endResetModel();
114}
115
116QString MauiModel::getFilterRoleName() const
117{
118 return m_filter;
119}
120
121void MauiModel::setSortOrder(const Qt::SortOrder &sortOrder)
122{
123 if (this->m_sortOrder == sortOrder)
124 return;
125
126 this->m_sortOrder = sortOrder;
127 Q_EMIT this->sortOrderChanged(this->m_sortOrder);
128 this->sort(0, this->m_sortOrder);
129}
130
131Qt::SortOrder MauiModel::getSortOrder() const
132{
133 return this->m_sortOrder;
134}
135
136void MauiModel::setSort(const QString &sort)
137{
138 if (this->m_sort == sort)
139 return;
140
141 this->m_sort = sort;
142 Q_EMIT this->sortChanged(this->m_sort);
143 this->setSortRole(FMH::MODEL_NAME_KEY[sort]);
144 this->sort(0, this->m_sortOrder);
145}
146
147QString MauiModel::getSort() const
148{
149 return this->m_sort;
150}
151
152int MauiModel::count() const
153{
154 return this->rowCount();
155}
156
158{
159 return this->mapFromSource(this->m_model->index(index, 0)).row();
160}
161
162int MauiModel::mappedToSource(const int &index) const
163{
164 return this->mapToSource(this->index(index, 0)).row();
165}
166
167void MauiModel::setFilterRoleName(QString filter)
168{
169 if (m_filterRoleName == filter)
170 return;
171
172 m_filterRoleName = filter;
173 Q_EMIT filterRoleNameChanged(m_filterRoleName);
174 this->setFilterRole(FMH::MODEL_NAME_KEY[m_filterRoleName]);
175}
176
177bool MauiModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
178{
179 if (this->filterRole() != Qt::DisplayRole) {
180 QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
181 const auto data = this->sourceModel()->data(index, this->filterRole()).toString();
182 return data.contains(this->filterRegularExpression());
183 }
184
185 const auto roleNames = this->sourceModel()->roleNames();
186 for (const auto &role : roleNames) {
187 QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
188 const auto data = this->sourceModel()->data(index, FMH::MODEL_NAME_KEY[role]).toString();
189 if (data.contains(this->filterRegularExpression()))
190 return true;
191 else
192 continue;
193 }
194
195 return false;
196}
197
198MauiList *MauiModel::getList() const
199{
200 return this->m_list;
201}
202
203void MauiModel::PrivateAbstractListModel::setUpList()
204{
206
207 if (m_model->getList())
208 m_model->getList()->disconnect(this);
209
210 if (m_model->getList()) {
211 connect(
212 m_model->getList(),
214 this,
215 [this](int index) {
216 beginInsertRows(QModelIndex(), index, index);
217 },
219
220 connect(
221 m_model->getList(),
223 this,
224 [this]() {
225 const int index = m_model->getList()->getCount();
226 beginInsertRows(QModelIndex(), index, index);
227 },
229
230 connect(
231 m_model->getList(),
233 this,
234 [this](uint count) {
235 const int index = m_model->getList()->getCount();
236 beginInsertRows(QModelIndex(), index, index + count - 1);
237 },
239
240 connect(
241 m_model->getList(),
243 this,
244 [this]() {
245 endInsertRows();
246 },
248
249 connect(
250 m_model->getList(),
252 this,
253 [this](int index) {
254 beginRemoveRows(QModelIndex(), index, index);
255 },
257
258 connect(
259 m_model->getList(),
261 this,
262 [this]() {
263 endRemoveRows();
264 },
266
267 connect(
268 m_model->getList(),
270 this,
271 [this](int index, QVector<int> roles) {
272 Q_EMIT this->dataChanged(this->m_model->index(index, 0), this->m_model->index(index, 0), roles);
273 },
275
276 connect(
277 m_model->getList(),
279 this,
280 [this]() {
281 beginResetModel();
282 },
284
285 connect(
286 m_model->getList(),
288 this,
289 [this]() {
290 endResetModel();
291 },
293
294 connect(
295 m_model->getList(),
297 m_model, &MauiModel::move,
299 }
300
302}
303
304void MauiModel::setList(MauiList *value)
305{
306 if(value && value != this->m_list)
307 {
308 this->m_list = value;
309 this->m_list->modelHooked();
310
311 this->m_model->setUpList();
312 Q_EMIT this->listChanged();
313
314 this->setSourceModel(this->m_model);
315 this->setDynamicSortFilter(true);
316 }
317}
318
319MauiModel::PrivateAbstractListModel::PrivateAbstractListModel(MauiModel *model)
320 : QAbstractListModel(model)
321 , m_model(model)
322{
323 connect(
324 this,
326 this,
327 [this](QModelIndex, int, int) {
328 if (m_model->getList()) {
329 Q_EMIT this->m_model->countChanged();
330 }
331 },
333
334 connect(
335 this,
337 this,
338 [this](QModelIndex, int, int) {
339 if (m_model->getList()) {
340 Q_EMIT this->m_model->countChanged();
341 }
342 },
344}
345
346int MauiModel::PrivateAbstractListModel::rowCount(const QModelIndex &parent) const
347{
348 if (parent.isValid() || !m_model->getList())
349 {
350 return 0;
351 }
352
353 return m_model->getList()->getCount();
354}
355
356
357QVariant MauiModel::PrivateAbstractListModel::data(const QModelIndex &index, int role) const
358{
359 if (!index.isValid() || !m_model->getList())
360 return QVariant();
361
362 auto value = m_model->getList()->getItem(index.row()).value(static_cast<FMH::MODEL_KEY>(role));
363
364 if (role == FMH::MODEL_KEY::ADDDATE || role == FMH::MODEL_KEY::DATE || role == FMH::MODEL_KEY::MODIFIED || role == FMH::MODEL_KEY::RELEASEDATE) {
365 const auto date = QDateTime::fromString(value, Qt::TextDate);
366 if (date.isValid())
367 return date;
368 }
369
370 return value;
371}
372
373bool MauiModel::PrivateAbstractListModel::setData(const QModelIndex &index, const QVariant &value, int role)
374{
375 Q_UNUSED(index);
376 Q_UNUSED(value);
377 Q_UNUSED(role);
378
379 return false;
380}
381
382Qt::ItemFlags MauiModel::PrivateAbstractListModel::flags(const QModelIndex &index) const
383{
384 if (!index.isValid())
385 return Qt::NoItemFlags;
386
387 return Qt::ItemIsEditable; // FIXME: Implement me!
388}
389
390QHash<int, QByteArray> MauiModel::PrivateAbstractListModel::roleNames() const
391{
393 const auto keys = FMH::MODEL_NAME.keys();
394
395 for (const auto &key : keys)
396 {
397 names[key] = QString(FMH::MODEL_NAME[key]).toUtf8();
398 }
399
400 return names;
401}
402
403bool MauiModel::move(const int &index, const int &to)
404{
405 if(index == to)
406 return false;
407
408 if(index>=0 && index< count())
409 {
410 if(to >= count() || to < 0)
411 return false;
412
413 beginMoveRows(QModelIndex(), index, index, QModelIndex(), index < to ? to+1 : to);
414 endMoveRows();
415 }
416
417 return true;
418}
419
420/*!
421 * Must be reimplemented, because moving rows should be possible
422 * \brief ListModel::moveRows
423 * \param sourceParent
424 * \param sourceRow
425 * \param count
426 * \param destinationParent
427 * \param destinationChild
428 * \return
429 */
430bool MauiModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) {
431 if (sourceRow < 0
432 //|| sourceRow + count - 1 >= rowCount(sourceParent)
433 || destinationChild <= 0
434 //|| destinationChild > rowCount(destinationParent)
435 || sourceRow == destinationChild - 1
436 || count <= 0) {
437 return false;
438 }
439
440 return true;
441}
442
443bool MauiModel::moveRow(const QModelIndex &sourceParent, int sourceRow, const QModelIndex &destinationParent, int destinationChild) {
444
445 return true;
446}
447
MauiList class.
Definition mauilist.h:180
virtual void modelHooked()
This function is called once the MauiList has been hooked to the MauiModel, using the MauiModel::list...
Definition mauilist.h:221
void preItemAppendedAt(int index)
This signal should be emitted by the implementation before a new item has been inserted at a given in...
void preItemAppended()
This signal should be emitted by the implementation before appending a new item to the list data mode...
void updateModel(int index, QVector< int > roles)
This signal should be emitted by the implementation when changes have been done in the list data mode...
void postItemAppended()
This signal should be emitted by the implementation after one or multiple new items have finished bei...
void preItemRemoved(int index)
This signal should be emitted by the implementation before an item has been removed at the given inde...
void preItemsAppended(uint count)
This signal should be emitted by the implementation before appending a multiple new items to the list...
void itemMoved(int index, int to)
This signal should be emitted by the implementation when an item has been moved from one index positi...
void preListChanged()
This signal should be emitted by the implementation before the list data model has been assigned or p...
void postListChanged()
This signal should be emitted by the implementation after the list data model is set and done.
void postItemRemoved()
This signal should be emitted by the implementation after an item has been successfully removed from ...
The MauiModel class.
Definition mauimodel.h:54
QVariantMap get(const int &index) const
Returns an item in the model.
Definition mauimodel.cpp:32
void clearFilters()
Restores the model if filtered, and clears all the filters set with the filter and filters properties...
Definition mauimodel.cpp:98
int mappedFromSource(const int &index) const
Maps a given index from the base list to the model, in case the model has been filtered or sorted,...
int mappedToSource(const int &) const
Given an index from the filtered or sorted model it returns the mapped index to the original list ind...
bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) override
ListModel::moveRows.
QVariantList getAll() const
Returns all the items in the list represented as a QVariantList to be able to be used in QML.
Definition mauimodel.cpp:45
static const QHash< QString, MODEL_KEY > MODEL_NAME_KEY
The mapping of a string text into a FMH::MODEL_KEY.
Definition fmh.h:378
static const QHash< MODEL_KEY, QString > MODEL_NAME
The mapping of the FMH::MODEL_KEY enum values to its string representation.
Definition fmh.h:219
MODEL_KEY
The MODEL_KEY enum values.
Definition fmh.h:64
bool beginMoveRows(const QModelIndex &sourceParent, int sourceFirst, int sourceLast, const QModelIndex &destinationParent, int destinationChild)
void rowsInserted(const QModelIndex &parent, int first, int last)
void rowsRemoved(const QModelIndex &parent, int first, int last)
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
virtual QHash< int, QByteArray > roleNames() const const override
QDateTime fromString(QStringView string, QStringView format, QCalendar cal)
QList< Key > keys() const const
const_reference at(qsizetype i) const const
void clear()
qsizetype count() const const
bool isValid() const const
int row() const const
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool disconnect(const QMetaObject::Connection &connection)
QObject * parent() const const
QString escape(QStringView str)
virtual QVariant data(const QModelIndex &index, int role) const const override
void setDynamicSortFilter(bool enable)
void setFilterRegularExpression(const QRegularExpression &regularExpression)
void setFilterRole(int role)
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
virtual QModelIndex mapFromSource(const QModelIndex &sourceIndex) const const override
virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const const override
virtual int rowCount(const QModelIndex &parent) const const override
void setFilterFixedString(const QString &pattern)
virtual void setSourceModel(QAbstractItemModel *sourceModel) override
void setSortRole(int role)
void clear()
QByteArray toUtf8() const const
DirectConnection
TextDate
DisplayRole
typedef ItemFlags
SortOrder
QFuture< void > filter(QThreadPool *pool, Sequence &sequence, KeepFunctor &&filterFunction)
void * data()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 17 2024 11:56:16 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.