1/****************************************************************************
2**
3** Copyright (C) 2018 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include <QtCore/QtCore>
30#include <QtGui/QStandardItemModel>
31
32class TestModel : public QAbstractTableModel
33{
34 Q_OBJECT
35 Q_PROPERTY(int rowCount READ rowCount WRITE setRowCount NOTIFY rowCountChanged)
36 Q_PROPERTY(int columnCount READ columnCount WRITE setColumnCount NOTIFY columnCountChanged)
37
38public:
39 TestModel(QObject *parent = nullptr)
40 : QAbstractTableModel(parent)
41 {}
42
43 TestModel(int rows, int columns, QObject *parent = nullptr)
44 : QAbstractTableModel(parent)
45 , m_rows(rows)
46 , m_columns(columns)
47 {}
48
49 TestModel(int rows, int columns, bool dataCanBeFetched, QObject *parent = nullptr)
50 : QAbstractTableModel(parent)
51 , m_rows(rows)
52 , m_columns(columns)
53 , m_dataCanBeFetched(dataCanBeFetched)
54 {}
55
56 int rowCount(const QModelIndex & = QModelIndex()) const override { return m_rows; }
57 void setRowCount(int count) { beginResetModel(); m_rows = count; emit rowCountChanged(); endResetModel(); }
58
59 int columnCount(const QModelIndex & = QModelIndex()) const override { return m_columns; }
60 void setColumnCount(int count) { beginResetModel(); m_columns = count; emit columnCountChanged(); endResetModel(); }
61
62 QVariant data(const QModelIndex &index, int role) const override
63 {
64 if (!index.isValid() || role != Qt::DisplayRole)
65 return QVariant();
66
67 int serializedIndex = index.row() + (index.column() * m_columns);
68 if (modelData.contains(key: serializedIndex))
69 return modelData.value(key: serializedIndex);
70 return QStringLiteral("%1").arg(a: index.row());
71 }
72
73 Q_INVOKABLE QVariant dataFromSerializedIndex(int index) const
74 {
75 if (modelData.contains(key: index))
76 return modelData.value(key: index);
77 return QString();
78 }
79
80 QHash<int, QByteArray> roleNames() const override
81 {
82 return { {Qt::DisplayRole, "display"} };
83 }
84
85 Q_INVOKABLE void setModelData(const QPoint &cell, const QSize &span, const QString &string)
86 {
87 for (int c = 0; c < span.width(); ++c) {
88 for (int r = 0; r < span.height(); ++r) {
89 const int changedRow = cell.y() + r;
90 const int changedColumn = cell.x() + c;
91 const int serializedIndex = changedRow + (changedColumn * m_rows);
92 modelData.insert(key: serializedIndex, value: string);
93 }
94 }
95
96 const auto topLeftIndex = createIndex(arow: cell.y(), acolumn: cell.x(), adata: nullptr);
97 const auto bottomRightIndex = createIndex(arow: cell.y() + span.height() - 1, acolumn: cell.x() + span.width() - 1, adata: nullptr);
98 emit dataChanged(topLeft: topLeftIndex, bottomRight: bottomRightIndex);
99 }
100
101 bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override
102 {
103 if (row < 0 || count <= 0)
104 return false;
105
106 beginInsertRows(parent, first: row, last: row + count - 1);
107 m_rows += count;
108 endInsertRows();
109 return true;
110 }
111
112 bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override
113 {
114 if (!checkIndex(index: createIndex(arow: row, acolumn: 0)) || !checkIndex(index: createIndex(arow: row + count - 1, acolumn: 0)))
115 return false;
116
117 beginRemoveRows(parent, first: row, last: row + count - 1);
118 m_rows -= count;
119 for (int c = 0; c < m_columns; ++c) {
120 for (int r = 0; r < count; ++r) {
121 const int serializedIndex = (row + r) + (c * m_rows);
122 modelData.remove(key: serializedIndex);
123 }
124 }
125 endRemoveRows();
126 return true;
127 }
128
129 bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override
130 {
131 if (column < 0 || count <= 0)
132 return false;
133
134 beginInsertColumns(parent, first: column, last: column + count - 1);
135 m_columns += count;
136 endInsertColumns();
137 return true;
138 }
139
140 bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override
141 {
142 if (!checkIndex(index: createIndex(arow: 0, acolumn: column)) || !checkIndex(index: createIndex(arow: 0, acolumn: column + count - 1)))
143 return false;
144
145 beginRemoveColumns(parent, first: column, last: column + count - 1);
146 m_columns -= count;
147 endRemoveColumns();
148 return true;
149 }
150
151 bool canFetchMore(const QModelIndex &parent) const override
152 {
153 Q_UNUSED(parent)
154 return m_dataCanBeFetched;
155 }
156
157 void swapRows(int row1, int row2)
158 {
159 layoutAboutToBeChanged();
160 Q_ASSERT(modelData.contains(row1));
161 Q_ASSERT(modelData.contains(row2));
162 const QString tmp = modelData[row1];
163 modelData[row1] = modelData[row2];
164 modelData[row2] = tmp;
165 layoutChanged();
166 }
167
168 void fetchMore(const QModelIndex &parent) override
169 {
170 Q_UNUSED(parent)
171 addRow(row: m_rows - 1);
172 }
173
174 void clear() {
175 beginResetModel();
176 m_rows = 0;
177 m_columns = 0;
178 modelData.clear();
179 endResetModel();
180 }
181
182 Q_INVOKABLE void addRow(int row)
183 {
184 insertRow(arow: row, aparent: QModelIndex());
185 }
186
187signals:
188 void rowCountChanged();
189 void columnCountChanged();
190
191private:
192 int m_rows = 0;
193 int m_columns = 0;
194 bool m_dataCanBeFetched = false;
195 QHash<int, QString> modelData;
196};
197
198#define TestModelAsVariant(...) QVariant::fromValue(QSharedPointer<TestModel>(new TestModel(__VA_ARGS__)))
199

source code of qtdeclarative/tests/auto/quick/qquicktableview/testmodel.h