1
/****************************************************************************
2
**
3
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4
** All rights reserved.
5
** Contact: Nokia Corporation (qt-info@nokia.com)
6
**
7
** This file is part of the test suite of the Qt Toolkit.
8
**
9
** $QT_BEGIN_LICENSE:LGPL$
10
** GNU Lesser General Public License Usage
11
** This file may be used under the terms of the GNU Lesser General Public
12
** License version 2.1 as published by the Free Software Foundation and
13
** appearing in the file LICENSE.LGPL included in the packaging of this
14
** file. Please review the following information to ensure the GNU Lesser
15
** General Public License version 2.1 requirements will be met:
16
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17
**
18
** In addition, as a special exception, Nokia gives you certain additional
19
** rights. These rights are described in the Nokia Qt LGPL Exception
20
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21
**
22
** GNU General Public License Usage
23
** Alternatively, this file may be used under the terms of the GNU General
24
** Public License version 3.0 as published by the Free Software Foundation
25
** and appearing in the file LICENSE.GPL included in the packaging of this
26
** file. Please review the following information to ensure the GNU General
27
** Public License version 3.0 requirements will be met:
28
** http://www.gnu.org/copyleft/gpl.html.
29
**
30
** Other Usage
31
** Alternatively, this file may be used in accordance with the terms and
32
** conditions contained in a signed written agreement between you and Nokia.
33
**
34
**
35
**
36
**
37
**
38
** $QT_END_LICENSE$
39
**
40
****************************************************************************/
41
42
43
#include <QtTest/QtTest>
44
#include <QtGui/QtGui>
45
46
#include "modeltest.h"
47
#include "dynamictreemodel.h"
48
49
50
class tst_ModelTest : public QObject
51
{
52
    Q_OBJECT
53
54
public:
55
    tst_ModelTest() {}
56
    virtual ~tst_ModelTest() {}
57
58
public slots:
59
    void initTestCase();
60
    void cleanupTestCase();
61
    void init();
62
    void cleanup();
63
64
private slots:
65
    void stringListModel();
66
    void treeWidgetModel();
67
    void standardItemModel();
68
    void testInsertThroughProxy();
69
    void moveSourceItems();
70
    void testResetThroughProxy();
71
};
72
73
74
75
void tst_ModelTest::initTestCase()
76
{
77
}
78
79
void tst_ModelTest::cleanupTestCase()
80
{
81
}
82
83
void tst_ModelTest::init()
84
{
85
86
}
87
88
void tst_ModelTest::cleanup()
89
{
90
}
91
/*
92
  tests
93
*/
94
95
void tst_ModelTest::stringListModel()
96
{
97
    QStringListModel model;
98
    QSortFilterProxyModel proxy;
99
100
    ModelTest t1(&model);
101
    ModelTest t2(&proxy);
102
103
    proxy.setSourceModel(&model);
104
105
    model.setStringList(QStringList() << "2" << "3" << "1");
106
    model.setStringList(QStringList() << "a" << "e" << "plop" << "b" << "c" );
107
108
    proxy.setDynamicSortFilter(true);
109
    proxy.setFilterRegExp(QRegExp("[^b]"));
110
}
111
112
void tst_ModelTest::treeWidgetModel()
113
{
114
    QTreeWidget widget;
115
116
    ModelTest t1(widget.model());
117
118
    QTreeWidgetItem *root = new QTreeWidgetItem(&widget, QStringList("root"));
119
    for (int i = 0; i < 20; ++i) {
120
        new QTreeWidgetItem(root, QStringList(QString::number(i)));
121
    }
122
    QTreeWidgetItem *remove = root->child(2);
123
    root->removeChild(remove);
124
    QTreeWidgetItem *parent = new QTreeWidgetItem(&widget, QStringList("parent"));
125
    new QTreeWidgetItem(parent, QStringList("child"));
126
    widget.setItemHidden(parent, true);
127
128
    widget.sortByColumn(0);
129
}
130
131
void tst_ModelTest::standardItemModel()
132
{
133
    QStandardItemModel model(10,10);
134
    QSortFilterProxyModel proxy;
135
136
137
    ModelTest t1(&model);
138
    ModelTest t2(&proxy);
139
140
    proxy.setSourceModel(&model);
141
142
    model.insertRows(2, 5);
143
    model.removeRows(4, 5);
144
145
    model.insertColumns(2, 5);
146
    model.removeColumns(4, 5);
147
148
    model.insertRows(0,5, model.index(1,1));
149
    model.insertColumns(0,5, model.index(1,3));
150
}
151
152
void tst_ModelTest::testInsertThroughProxy()
153
{
154
    DynamicTreeModel *model = new DynamicTreeModel(this);
155
156
    QSortFilterProxyModel *proxy = new QSortFilterProxyModel(this);
157
    proxy->setSourceModel(model);
158
159
    new ModelTest(proxy, this);
160
161
    ModelInsertCommand *insertCommand = new ModelInsertCommand(model, this);
162
    insertCommand->setNumCols(4);
163
    insertCommand->setStartRow(0);
164
    insertCommand->setEndRow(9);
165
    // Parent is QModelIndex()
166
    insertCommand->doCommand();
167
168
    insertCommand = new ModelInsertCommand(model, this);
169
    insertCommand->setNumCols(4);
170
    insertCommand->setAncestorRowNumbers(QList<int>() << 5);
171
    insertCommand->setStartRow(0);
172
    insertCommand->setEndRow(9);
173
    insertCommand->doCommand();
174
175
    ModelMoveCommand *moveCommand = new ModelMoveCommand(model, this);
176
    moveCommand->setNumCols(4);
177
    moveCommand->setStartRow(0);
178
    moveCommand->setEndRow(0);
179
    moveCommand->setDestRow(9);
180
    moveCommand->setDestAncestors(QList<int>() << 5);
181
    moveCommand->doCommand();
182
}
183
184
/**
185
  Makes the persistent index list publicly accessible
186
*/
187
class AccessibleProxyModel : public QSortFilterProxyModel
188
{
189
    Q_OBJECT
190
public:
191
    AccessibleProxyModel(QObject *parent = 0) : QSortFilterProxyModel(parent) {}
192
193
    QModelIndexList persistent()
194
    {
195
        return persistentIndexList();
196
    }
197
};
198
199
class ObservingObject : public QObject
200
{
201
    Q_OBJECT
202
public:
203
    ObservingObject(AccessibleProxyModel  *proxy, QObject *parent = 0)
204
    : QObject(parent),
205
    m_proxy(proxy)
206
    {
207
        connect(m_proxy, SIGNAL(layoutAboutToBeChanged()), SLOT(storePersistent()));
208
        connect(m_proxy, SIGNAL(layoutChanged()), SLOT(checkPersistent()));
209
    }
210
211
public slots:
212
213
    void storePersistent(const QModelIndex &parent)
214
    {
215
        for (int row = 0; row < m_proxy->rowCount(parent); ++row) {
216
            QModelIndex proxyIndex = m_proxy->index(row, 0, parent);
217
            QModelIndex sourceIndex = m_proxy->mapToSource(proxyIndex);
218
            Q_ASSERT(proxyIndex.isValid());
219
            Q_ASSERT(sourceIndex.isValid());
220
            m_persistentSourceIndexes.append(sourceIndex);
221
            m_persistentProxyIndexes.append(proxyIndex);
222
            if (m_proxy->hasChildren(proxyIndex))
223
                storePersistent(proxyIndex);
224
        }
225
    }
226
227
    void storePersistent()
228
    {
229
      foreach(const QModelIndex &idx, m_persistentProxyIndexes)
230
        Q_ASSERT(idx.isValid()); // This is called from layoutAboutToBeChanged. Persistent indexes should be valid
231
232
        Q_ASSERT(m_proxy->persistent().isEmpty());
233
        storePersistent(QModelIndex());
234
        Q_ASSERT(!m_proxy->persistent().isEmpty());
235
    }
236
237
    void checkPersistent()
238
    {
239
        for (int row = 0; row < m_persistentProxyIndexes.size(); ++row) {
240
            QModelIndex updatedProxy = m_persistentProxyIndexes.at(row);
241
            QModelIndex updatedSource = m_persistentSourceIndexes.at(row);
242
        }
243
        for (int row = 0; row < m_persistentProxyIndexes.size(); ++row) {
244
            QModelIndex updatedProxy = m_persistentProxyIndexes.at(row);
245
            QModelIndex updatedSource = m_persistentSourceIndexes.at(row);
246
            QCOMPARE(m_proxy->mapToSource(updatedProxy), updatedSource);
247
        }
248
        m_persistentSourceIndexes.clear();
249
        m_persistentProxyIndexes.clear();
250
    }
251
252
private:
253
    AccessibleProxyModel  *m_proxy;
254
    QList<QPersistentModelIndex> m_persistentSourceIndexes;
255
    QList<QPersistentModelIndex> m_persistentProxyIndexes;
256
};
257
258
void tst_ModelTest::moveSourceItems()
259
{
260
    DynamicTreeModel *model = new DynamicTreeModel(this);
261
    AccessibleProxyModel *proxy = new AccessibleProxyModel(this);
262
    proxy->setSourceModel(model);
263
264
    ModelInsertCommand *insertCommand = new ModelInsertCommand(model, this);
265
    insertCommand->setStartRow(0);
266
    insertCommand->setEndRow(2);
267
    insertCommand->doCommand();
268
269
    insertCommand = new ModelInsertCommand(model, this);
270
    insertCommand->setAncestorRowNumbers(QList<int>() << 1);
271
    insertCommand->setStartRow(0);
272
    insertCommand->setEndRow(2);
273
    insertCommand->doCommand();
274
275
    ObservingObject observer(proxy);
276
277
    ModelMoveCommand *moveCommand = new ModelMoveCommand(model, this);
278
    moveCommand->setStartRow(0);
279
    moveCommand->setEndRow(0);
280
    moveCommand->setDestAncestors(QList<int>() << 1);
281
    moveCommand->setDestRow(0);
282
    moveCommand->doCommand();
283
}
284
285
void tst_ModelTest::testResetThroughProxy()
286
{
287
    DynamicTreeModel *model = new DynamicTreeModel(this);
288
289
    ModelInsertCommand *insertCommand = new ModelInsertCommand(model, this);
290
    insertCommand->setStartRow(0);
291
    insertCommand->setEndRow(2);
292
    insertCommand->doCommand();
293
294
    QPersistentModelIndex persistent = model->index(0, 0);
295
296
    AccessibleProxyModel *proxy = new AccessibleProxyModel(this);
297
    proxy->setSourceModel(model);
298
299
    ObservingObject observer(proxy);
300
    observer.storePersistent();
301
302
    ModelResetCommand *resetCommand = new ModelResetCommand(model, this);
303
    resetCommand->setNumCols(0);
304
    resetCommand->doCommand();
305
}
306
307
308
QTEST_MAIN(tst_ModelTest)
309
#include "tst_modeltest.moc"