File indexing completed on 2024-05-12 17:08:30
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 0012 /** 0013 * Attached property object for ComponentCacheProxyModel 0014 */ 0015 class ComponentCacheAttached : public QObject 0016 { 0017 Q_OBJECT 0018 Q_PROPERTY(QAbstractItemModel *model MEMBER m_model CONSTANT) 0019 Q_PROPERTY(int row MEMBER m_row CONSTANT) 0020 Q_PROPERTY(int column MEMBER m_column CONSTANT) 0021 0022 public: 0023 explicit ComponentCacheAttached(QObject *parent = nullptr); 0024 0025 QAbstractItemModel *m_model = nullptr; 0026 int m_row = -1; 0027 int m_column = -1; 0028 }; 0029 0030 /** 0031 * A proxy model that adds a cached component as an extra role. 0032 * 0033 * This proxy model will return an instance of \property component when data is 0034 * requested for the CachedComponentRole. If the instance does not yet exist, 0035 * it will be created. 0036 * 0037 * The referenced component can make use of the ComponentCacheAttached 0038 * attached property. 0039 * 0040 * This is mostly a helper for dealing with TableView and QSortFilterProxyModel, 0041 * which will cause some annoying reordering of cell delegates when sorting is 0042 * applied. 0043 */ 0044 class ComponentCacheProxyModel : public QIdentityProxyModel 0045 { 0046 Q_OBJECT 0047 Q_PROPERTY(QQmlComponent *component READ component WRITE setComponent NOTIFY componentChanged) 0048 0049 public: 0050 enum Roles { 0051 CachedComponentRole = Qt::UserRole + 88, 0052 }; 0053 Q_ENUM(Roles) 0054 0055 explicit ComponentCacheProxyModel(QObject *parent = nullptr); 0056 ~ComponentCacheProxyModel() override; 0057 0058 QHash<int, QByteArray> roleNames() const override; 0059 QVariant data(const QModelIndex &proxyIndex, int role) const override; 0060 void setSourceModel(QAbstractItemModel *sourceModel) override; 0061 0062 QQmlComponent *component() const; 0063 void setComponent(QQmlComponent *newComponent); 0064 Q_SIGNAL void componentChanged(); 0065 0066 Q_INVOKABLE void clear(); 0067 0068 static ComponentCacheAttached *qmlAttachedProperties(QObject *object) 0069 { 0070 return new ComponentCacheAttached(object); 0071 } 0072 0073 private: 0074 void onRowsRemoved(const QModelIndex &parent, int start, int end); 0075 void onColumnsRemoved(const QModelIndex &parent, int start, int end); 0076 void createPendingInstance(); 0077 0078 QQmlComponent *m_component = nullptr; 0079 QHash<QPersistentModelIndex, QObject *> m_instances; 0080 0081 mutable QVector<QPersistentModelIndex> m_pendingInstances; 0082 }; 0083 0084 QML_DECLARE_TYPEINFO(ComponentCacheProxyModel, QML_HAS_ATTACHED_PROPERTIES)