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 292 : ListItem(QObject* parent = nullptr) : FangObject(parent) {}
23 273 : 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 376 : 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 180 : 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, int count = 1);
73 :
74 : // QML ListModel-compatible API (for RearrangeableTreeView compatibility)
75 : Q_INVOKABLE QVariantMap get(int row) const;
76 : Q_INVOKABLE void setProperty(int row, const QString &name, QVariant value);
77 : Q_INVOKABLE void remove(int row, int count = 1);
78 :
79 : signals:
80 : void added(ListItem* item);
81 : void removed(ListItem* item);
82 :
83 : void selectedChanged(ListItem* selected);
84 : void selectedIndexChanged(int selectedIndex);
85 : void countChanged(int newCount);
86 :
87 : protected:
88 : // Returns the role # for a given role name, or -1 if it's invalid.
89 : int roleNameToRole(const QString& field_name) const;
90 :
91 : private slots:
92 : void handleItemChange();
93 :
94 : private:
95 : ListItem* m_prototype;
96 : QList<ListItem*> m_list;
97 : ListItem* _selected;
98 : QHash<QString, int> _roleNames;
99 : };
100 :
101 : #endif // LISTMODEL_H
|