File indexing completed on 2024-05-12 05:36:51
0001 /* 0002 * SPDX-FileCopyrightText: 2020 Arjen Hiemstra <ahiemstra@heimr.nl> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #pragma once 0008 0009 #include <QIdentityProxyModel> 0010 #include <QQmlComponent> 0011 #include <qqmlregistration.h> 0012 0013 /** 0014 * Attached property object for ComponentCacheProxyModel 0015 */ 0016 class ComponentCacheAttached : public QObject 0017 { 0018 Q_OBJECT 0019 Q_PROPERTY(QAbstractItemModel *model MEMBER m_model CONSTANT) 0020 Q_PROPERTY(int row MEMBER m_row CONSTANT) 0021 Q_PROPERTY(int column MEMBER m_column CONSTANT) 0022 QML_ANONYMOUS 0023 0024 public: 0025 explicit ComponentCacheAttached(QObject *parent = nullptr); 0026 0027 QAbstractItemModel *m_model = nullptr; 0028 int m_row = -1; 0029 int m_column = -1; 0030 }; 0031 0032 /** 0033 * A proxy model that adds a cached component as an extra role. 0034 * 0035 * This proxy model will return an instance of \property component when data is 0036 * requested for the CachedComponentRole. If the instance does not yet exist, 0037 * it will be created. 0038 * 0039 * The referenced component can make use of the ComponentCacheAttached 0040 * attached property. 0041 * 0042 * This is mostly a helper for dealing with TableView and QSortFilterProxyModel, 0043 * which will cause some annoying reordering of cell delegates when sorting is 0044 * applied. 0045 */ 0046 class ComponentCacheProxyModel : public QIdentityProxyModel 0047 { 0048 Q_OBJECT 0049 Q_PROPERTY(QQmlComponent *component READ component WRITE setComponent NOTIFY componentChanged) 0050 QML_ELEMENT 0051 QML_ATTACHED(ComponentCacheAttached) 0052 0053 public: 0054 enum Roles { 0055 CachedComponentRole = Qt::UserRole + 88, 0056 }; 0057 Q_ENUM(Roles) 0058 0059 explicit ComponentCacheProxyModel(QObject *parent = nullptr); 0060 ~ComponentCacheProxyModel() override; 0061 0062 QHash<int, QByteArray> roleNames() const override; 0063 QVariant data(const QModelIndex &proxyIndex, int role) const override; 0064 void setSourceModel(QAbstractItemModel *sourceModel) override; 0065 0066 QQmlComponent *component() const; 0067 void setComponent(QQmlComponent *newComponent); 0068 Q_SIGNAL void componentChanged(); 0069 0070 Q_INVOKABLE void clear(); 0071 0072 static ComponentCacheAttached *qmlAttachedProperties(QObject *object) 0073 { 0074 return new ComponentCacheAttached(object); 0075 } 0076 0077 private: 0078 void onRowsRemoved(const QModelIndex &parent, int start, int end); 0079 void onColumnsRemoved(const QModelIndex &parent, int start, int end); 0080 void createPendingInstance(); 0081 0082 QQmlComponent *m_component = nullptr; 0083 QHash<QPersistentModelIndex, QObject *> m_instances; 0084 0085 mutable QList<QPersistentModelIndex> m_pendingInstances; 0086 };