File indexing completed on 2024-05-12 05:36:09

0001 /*
0002  *   SPDX-FileCopyrightText: 2014 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
0003  *
0004  *   SPDX-License-Identifier: LGPL-2.0-or-later
0005  */
0006 
0007 #pragma once
0008 
0009 #include <QAbstractListModel>
0010 #include <qqmlregistration.h>
0011 
0012 /**
0013  * @class PaginateModel
0014  *
0015  * This class can be used to create representations of only a chunk of a model.
0016  *
0017  * With this component it will be possible to create views that only show a page
0018  * of a model, instead of drawing all the elements in the model.
0019  */
0020 class PaginateModel : public QAbstractListModel
0021 {
0022     Q_OBJECT
0023     QML_ELEMENT
0024 
0025     /** Holds the number of elements that will fit in a page */
0026     Q_PROPERTY(int pageSize READ pageSize WRITE setPageSize NOTIFY pageSizeChanged)
0027 
0028     /** Tells what is the first row shown in the model */
0029     Q_PROPERTY(int firstItem READ firstItem WRITE setFirstItem NOTIFY firstItemChanged)
0030 
0031     /** The model we will be proxying */
0032     Q_PROPERTY(QAbstractItemModel *sourceModel READ sourceModel WRITE setSourceModel NOTIFY sourceModelChanged)
0033 
0034     /** Among the totality of elements, indicates the one we're currently offering */
0035     Q_PROPERTY(int currentPage READ currentPage NOTIFY firstItemChanged)
0036 
0037     /** Provides the number of pages available, given the sourceModel size */
0038     Q_PROPERTY(int pageCount READ pageCount NOTIFY pageCountChanged)
0039 
0040     /** If enabled, ensures that pageCount and pageSize are the same. */
0041     Q_PROPERTY(bool staticRowCount READ hasStaticRowCount WRITE setStaticRowCount NOTIFY staticRowCountChanged)
0042 
0043 public:
0044     explicit PaginateModel(QObject *object = nullptr);
0045     ~PaginateModel() override;
0046 
0047     int pageSize() const;
0048     void setPageSize(int count);
0049 
0050     int firstItem() const;
0051     void setFirstItem(int row);
0052 
0053     /**
0054      * @returns Last visible item.
0055      *
0056      * Convenience function
0057      */
0058     int lastItem() const;
0059 
0060     QAbstractItemModel *sourceModel() const;
0061     void setSourceModel(QAbstractItemModel *model);
0062 
0063     QModelIndex mapToSource(const QModelIndex &idx) const;
0064     QModelIndex mapFromSource(const QModelIndex &idx) const;
0065     int rowCount(const QModelIndex &parent = QModelIndex()) const override;
0066     QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
0067 
0068     int currentPage() const;
0069     int pageCount() const;
0070     QHash<int, QByteArray> roleNames() const override;
0071 
0072     void setStaticRowCount(bool src);
0073     bool hasStaticRowCount() const;
0074 
0075     /** Display the first rows of the model */
0076     Q_SCRIPTABLE void firstPage();
0077 
0078     /** Display the rows right after the ones that are currently being served */
0079     Q_SCRIPTABLE void nextPage();
0080 
0081     /** Display the rows right before the ones that are currently being served */
0082     Q_SCRIPTABLE void previousPage();
0083 
0084     /** Display the last set of rows of the source model */
0085     Q_SCRIPTABLE void lastPage();
0086 
0087 private Q_SLOTS:
0088     void _k_sourceRowsAboutToBeInserted(const QModelIndex &parent, int start, int end);
0089     void _k_sourceRowsInserted(const QModelIndex &parent, int start, int end);
0090     void _k_sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
0091     void _k_sourceRowsRemoved(const QModelIndex &parent, int start, int end);
0092     void _k_sourceRowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest);
0093     void _k_sourceRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest);
0094 
0095     void _k_sourceColumnsAboutToBeInserted(const QModelIndex &parent, int start, int end);
0096     void _k_sourceColumnsInserted(const QModelIndex &parent, int start, int end);
0097     void _k_sourceColumnsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
0098     void _k_sourceColumnsRemoved(const QModelIndex &parent, int start, int end);
0099     void _k_sourceColumnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest);
0100     void _k_sourceColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest);
0101 
0102     void _k_sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles);
0103     void _k_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last);
0104 
0105     void _k_sourceModelAboutToBeReset();
0106     void _k_sourceModelReset();
0107 
0108 Q_SIGNALS:
0109     void pageSizeChanged();
0110     void firstItemChanged();
0111     void sourceModelChanged();
0112     void pageCountChanged();
0113     void staticRowCountChanged();
0114 
0115 private:
0116     bool canSizeChange() const;
0117     bool isIntervalValid(const QModelIndex &parent, int start, int end) const;
0118     int rowsByPageSize(int size) const;
0119 
0120     class PaginateModelPrivate;
0121     QScopedPointer<PaginateModelPrivate> d;
0122 };