22
33#include < functional>
44
5- #include < bit >
5+ #include < QtCore/qtmetamacros.h >
66#include < qabstractitemmodel.h>
77#include < qcontainerfwd.h>
88#include < qobject.h>
@@ -49,14 +49,11 @@ class UntypedObjectModel: public QAbstractListModel {
4949public:
5050 explicit UntypedObjectModel (QObject* parent): QAbstractListModel(parent) {}
5151
52- [[nodiscard]] qint32 rowCount (const QModelIndex& parent) const override ;
53- [[nodiscard]] QVariant data (const QModelIndex& index, qint32 role) const override ;
5452 [[nodiscard]] QHash<int , QByteArray> roleNames () const override ;
5553
56- [[nodiscard]] QList<QObject*> values () const { return this ->valuesList ; }
57- void removeAt (qsizetype index);
54+ [[nodiscard]] virtual QList<QObject*> values () = 0;
5855
59- Q_INVOKABLE qsizetype indexOf (QObject* object);
56+ Q_INVOKABLE virtual qsizetype indexOf (QObject* object) const = 0 ;
6057
6158 static UntypedObjectModel* emptyInstance ();
6259
@@ -71,15 +68,6 @@ class UntypedObjectModel: public QAbstractListModel {
7168 // / Sent immediately after an object is removed from the list.
7269 void objectRemovedPost (QObject* object, qsizetype index);
7370
74- protected:
75- void insertObject (QObject* object, qsizetype index = -1 );
76- bool removeObject (const QObject* object);
77-
78- // Assumes only one instance of a specific value
79- void diffUpdate (const QVector<QObject*>& newValues);
80-
81- QVector<QObject*> valuesList;
82-
8371private:
8472 static qsizetype valuesCount (QQmlListProperty<QObject>* property);
8573 static QObject* valueAt (QQmlListProperty<QObject>* property, qsizetype index);
@@ -90,14 +78,20 @@ class ObjectModel: public UntypedObjectModel {
9078public:
9179 explicit ObjectModel (QObject* parent): UntypedObjectModel(parent) {}
9280
93- [[nodiscard]] QVector<T*>& valueList () { return *std::bit_cast<QVector<T*>*>(&this ->valuesList ); }
94-
95- [[nodiscard]] const QVector<T*>& valueList () const {
96- return *std::bit_cast<const QVector<T*>*>(&this ->valuesList );
97- }
81+ [[nodiscard]] const QList<T*>& valueList () const { return this ->mValuesList ; }
82+ [[nodiscard]] QList<T*>& valueList () { return this ->mValuesList ; }
9883
9984 void insertObject (T* object, qsizetype index = -1 ) {
100- this ->UntypedObjectModel ::insertObject (object, index);
85+ auto iindex = index == -1 ? this ->mValuesList .length () : index;
86+ emit this ->objectInsertedPre (object, iindex);
87+
88+ auto intIndex = static_cast <qint32>(iindex);
89+ this ->beginInsertRows (QModelIndex (), intIndex, intIndex);
90+ this ->mValuesList .insert (iindex, object);
91+ this ->endInsertRows ();
92+
93+ emit this ->valuesChanged ();
94+ emit this ->objectInsertedPost (object, iindex);
10195 }
10296
10397 void insertObjectSorted (T* object, const std::function<bool (T*, T*)>& compare) {
@@ -110,17 +104,71 @@ class ObjectModel: public UntypedObjectModel {
110104 }
111105
112106 auto idx = iter - list.begin ();
113- this ->UntypedObjectModel ::insertObject (object, idx);
107+ this ->insertObject (object, idx);
108+ }
109+
110+ bool removeObject (const T* object) {
111+ auto index = this ->mValuesList .indexOf (object);
112+ if (index == -1 ) return false ;
113+
114+ this ->removeAt (index);
115+ return true ;
114116 }
115117
116- void removeObject (const T* object) { this ->UntypedObjectModel ::removeObject (object); }
118+ void removeAt (qsizetype index) {
119+ auto * object = this ->mValuesList .at (index);
120+ emit this ->objectRemovedPre (object, index);
121+
122+ auto intIndex = static_cast <qint32>(index);
123+ this ->beginRemoveRows (QModelIndex (), intIndex, intIndex);
124+ this ->mValuesList .removeAt (index);
125+ this ->endRemoveRows ();
126+
127+ emit this ->valuesChanged ();
128+ emit this ->objectRemovedPost (object, index);
129+ }
117130
118131 // Assumes only one instance of a specific value
119- void diffUpdate (const QVector<T*>& newValues) {
120- this ->UntypedObjectModel ::diffUpdate (*std::bit_cast<const QVector<QObject*>*>(&newValues));
132+ void diffUpdate (const QList<T*>& newValues) {
133+ for (qsizetype i = 0 ; i < this ->mValuesList .length ();) {
134+ if (newValues.contains (this ->mValuesList .at (i))) i++;
135+ else this ->removeAt (i);
136+ }
137+
138+ qsizetype oi = 0 ;
139+ for (auto * object: newValues) {
140+ if (this ->mValuesList .length () == oi || this ->mValuesList .at (oi) != object) {
141+ this ->insertObject (object, oi);
142+ }
143+
144+ oi++;
145+ }
121146 }
122147
123148 static ObjectModel<T>* emptyInstance () {
124149 return static_cast <ObjectModel<T>*>(UntypedObjectModel::emptyInstance ());
125150 }
151+
152+ [[nodiscard]] qint32 rowCount (const QModelIndex& parent) const override {
153+ if (parent != QModelIndex ()) return 0 ;
154+ return static_cast <qint32>(this ->mValuesList .length ());
155+ }
156+
157+ [[nodiscard]] QVariant data (const QModelIndex& index, qint32 role) const override {
158+ if (role != Qt::UserRole) return QVariant ();
159+ // Values must be QObject derived, but we can't assert that here without breaking forward decls,
160+ // so no static_cast.
161+ return QVariant::fromValue (reinterpret_cast <QObject*>(this ->mValuesList .at (index.row ())));
162+ }
163+
164+ qsizetype indexOf (QObject* object) const override {
165+ return this ->mValuesList .indexOf (reinterpret_cast <T*>(object));
166+ }
167+
168+ [[nodiscard]] QList<QObject*> values () override {
169+ return *reinterpret_cast <QList<QObject*>*>(&this ->mValuesList );
170+ }
171+
172+ private:
173+ QList<T*> mValuesList ;
126174};
0 commit comments