Line data Source code
1 : /*
2 : * Author: Christophe Dumez <dchris@gmail.com>
3 : * License: Public domain (No attribution required)
4 : * Website: http://cdumez.blogspot.com/
5 : * Version: 1.0
6 : */
7 :
8 : #ifndef LISTMODEL_H
9 : #define LISTMODEL_H
10 :
11 : #include <QAbstractListModel>
12 : #include <QList>
13 : #include <QVariant>
14 : #include "../FangObject.h"
15 :
16 : class FeedItem;
17 :
18 : class ListItem: public FangObject {
19 : Q_OBJECT
20 :
21 : public:
22 108 : ListItem(QObject* parent = nullptr) : FangObject(parent) {}
23 89 : virtual ~ListItem() {}
24 0 : virtual QString id() const { return "invalid id"; }
25 0 : virtual QVariant data(int role) const { Q_UNUSED(role); return QVariant(); }
26 0 : virtual bool setData(const QVariant &value, int role) { Q_UNUSED(value); Q_UNUSED(role); return false; }
27 0 : virtual Qt::ItemFlags flags() const { return Qt::NoItemFlags; }
28 0 : virtual QHash<int, QByteArray> roleNames() const { return QHash<int, QByteArray>(); }
29 :
30 : signals:
31 : void dataChanged();
32 : };
33 :
34 : class ListModel : public QAbstractListModel
35 : {
36 : Q_OBJECT
37 :
38 : // Must manually set in C++ layer
39 : Q_PROPERTY(ListItem* selected READ selected WRITE setSelected NOTIFY selectedChanged)
40 : Q_PROPERTY(int selectedIndex READ selectedIndex WRITE setSelectedIndex NOTIFY selectedIndexChanged)
41 : Q_PROPERTY(int count READ count NOTIFY countChanged)
42 :
43 : public:
44 : explicit ListModel(ListItem* prototype, QObject* parent = nullptr);
45 : ~ListModel();
46 : int rowCount(const QModelIndex &parent = QModelIndex()) const;
47 104 : inline int count() const { return rowCount(); }
48 : QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
49 : Q_INVOKABLE QVariant dataByField(int row, const QString &field_name) const;
50 : bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
51 : Qt::ItemFlags flags(const QModelIndex &index) const;
52 : void appendRow(ListItem* item);
53 : void appendRows(const QList<ListItem*> &items);
54 : void insertRow(int row, ListItem* item);
55 : Q_INVOKABLE bool removeRow(int row, const QModelIndex &parent = QModelIndex());
56 : bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
57 : bool removeItem(const ListItem* item);
58 : ListItem* takeRow(int row);
59 : ListItem* find(const QString &id) const;
60 : QModelIndex indexFromItem(const ListItem* item) const;
61 : void clear();
62 0 : inline QHash<int, QByteArray> roleNames() const { return m_prototype->roleNames(); }
63 44 : inline ListItem* row(int row) { return m_list.at(row); }
64 0 : Q_INVOKABLE inline FeedItem* rowAs(int row) { return (FeedItem*)(m_list.at(row)); }
65 0 : inline ListItem* selected() { return _selected; }
66 : void setSelected(ListItem* selected);
67 : int selectedIndex();
68 : void setSelectedIndex(int selectedIndex);
69 :
70 : public slots:
71 : void setData(int row, const QString &field_name, QVariant new_value);
72 : void move(int from, int to);
73 :
74 : signals:
75 : void added(ListItem* item);
76 : void removed(ListItem* item);
77 :
78 : void selectedChanged(ListItem* selected);
79 : void selectedIndexChanged(int selectedIndex);
80 : void countChanged(int newCount);
81 :
82 : protected:
83 : // Returns the role # for a given role name, or -1 if it's invalid.
84 : int roleNameToRole(const QString& field_name) const;
85 :
86 : private slots:
87 : void handleItemChange();
88 :
89 : private:
90 : ListItem* m_prototype;
91 : QList<ListItem*> m_list;
92 : ListItem* _selected;
93 : QHash<QString, int> _roleNames;
94 : };
95 :
96 : #endif // LISTMODEL_H
|