]> cloud.milkyroute.net Git - dolphin.git/blob - src/tests/dolphintreeviewtest.cpp
Add unit test for bug 201459.
[dolphin.git] / src / tests / dolphintreeviewtest.cpp
1 /***************************************************************************
2 * Copyright (C) 2010 by Frank Reininghaus (frank78ac@googlemail.com) *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
18 ***************************************************************************/
19
20 #include <qtest_kde.h>
21
22 #include "views/dolphintreeview.h"
23
24 #include <qtestkeyboard.h>
25 #include <qtestmouse.h>
26 #include <QtGui/QStringListModel>
27
28 class DolphinTreeViewTest : public QObject
29 {
30 Q_OBJECT
31
32 private slots:
33
34 void bug201459_firstLetterAndThenShiftClickSelection();
35 void bug218114_visualRegionForSelection();
36
37 };
38
39 /**
40 * TestView is a simple view class derived from DolphinTreeView.
41 * It makes sure that the visualRect for each index contains only the item text as
42 * returned by QAbstractItemModel::data(...) for the role Qt::DisplayRole.
43 *
44 * We have to check that DolphinTreeView handles the case of visualRects with different widths
45 * correctly because this is the case in DolphinDetailsView which is derived from DolphinTreeView.
46 */
47
48 class TestView : public DolphinTreeView
49 {
50 Q_OBJECT
51
52 public:
53
54 TestView(QWidget* parent = 0) : DolphinTreeView(parent) {};
55 ~TestView() {};
56
57 QRect visualRect(const QModelIndex& index) const {
58 QRect rect = DolphinTreeView::visualRect(index);
59
60 const QStyleOptionViewItem option = viewOptions();
61 const QFontMetrics fontMetrics(option.font);
62 int width = option.decorationSize.width() + fontMetrics.width(model()->data(index).toString());
63
64 rect.setWidth(width);
65 return rect;
66 }
67
68 };
69
70 /**
71 * When the first letter of a file name is pressed, this file becomes the current item
72 * and gets selected. If the user then Shift-clicks another item, it is expected that
73 * all items between these two items get selected. Before the bug
74 *
75 * https://bugs.kde.org/show_bug.cgi?id=201459
76 *
77 * was fixed, this was not the case: the starting point for the Shift-selection was not
78 * updated if an item was selected by pressing the first letter of the file name.
79 */
80
81 void DolphinTreeViewTest::bug201459_firstLetterAndThenShiftClickSelection()
82 {
83 QStringList items;
84 items << "a" << "b" << "c" << "d" << "e";
85 QStringListModel model(items);
86
87 QModelIndex index[5];
88 for (int i = 0; i < 5; i++) {
89 index[i] = model.index(i, 0);
90 }
91
92 DolphinTreeView view;
93 view.setModel(&model);
94 view.setSelectionMode(QAbstractItemView::ExtendedSelection);
95 view.resize(400, 400);
96 view.show();
97 QTest::qWaitForWindowShown(&view);
98
99 QItemSelectionModel* selectionModel = view.selectionModel();
100 QModelIndexList selectedIndexes = selectionModel->selectedIndexes();
101 QCOMPARE(selectedIndexes.count(), 0);
102
103 // Control-click item 0 ("a")
104 QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, view.visualRect(index[0]).center());
105 QCOMPARE(view.currentIndex(), index[0]);
106 selectedIndexes = selectionModel->selectedIndexes();
107 QCOMPARE(selectedIndexes.count(), 1);
108 QVERIFY(selectedIndexes.contains(index[0]));
109
110 // Press "c", such that item 2 ("c") should be the current one.
111 QTest::keyClick(view.viewport(), Qt::Key_C);
112 QCOMPARE(view.currentIndex(), index[2]);
113 selectedIndexes = selectionModel->selectedIndexes();
114 QCOMPARE(selectedIndexes.count(), 1);
115 QVERIFY(selectedIndexes.contains(index[2]));
116
117 // Now Shift-Click the last item ("e"). We expect that 3 items ("c", "d", "e") are selected.
118 QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ShiftModifier, view.visualRect(index[4]).center());
119 QCOMPARE(view.currentIndex(), index[4]);
120 selectedIndexes = selectionModel->selectedIndexes();
121 QCOMPARE(selectedIndexes.count(), 3);
122 QVERIFY(selectedIndexes.contains(index[2]));
123 QVERIFY(selectedIndexes.contains(index[3]));
124 QVERIFY(selectedIndexes.contains(index[4]));
125 }
126
127 /**
128 * QTreeView assumes implicitly that the width of each item's visualRect is the same. This leads to painting
129 * problems in Dolphin if items with different widths are in one QItemSelectionRange, see
130 *
131 * https://bugs.kde.org/show_bug.cgi?id=218114
132 *
133 * To fix this, DolphinTreeView has a custom implementation of visualRegionForSelection(). The following
134 * unit test checks that.
135 */
136
137 void DolphinTreeViewTest::bug218114_visualRegionForSelection()
138 {
139 QStringList items;
140 items << "a" << "an item with a long name" << "a";
141 QStringListModel model(items);
142
143 QModelIndex index0 = model.index(0, 0);
144 QModelIndex index1 = model.index(1, 0);
145 QModelIndex index2 = model.index(2, 0);
146
147 TestView view;
148 view.setModel(&model);
149 view.setSelectionMode(QAbstractItemView::ExtendedSelection);
150 view.resize(400, 400);
151 view.show();
152 QTest::qWaitForWindowShown(&view);
153
154 // First check that the width of index1 is larger than that of index0 and index2 (this triggers the bug).
155
156 QVERIFY(view.visualRect(index0).width() < view.visualRect(index1).width());
157 QVERIFY(view.visualRect(index2).width() < view.visualRect(index1).width());
158
159 // Select all items in one go.
160
161 view.selectAll();
162 const QItemSelection selection = view.selectionModel()->selection();
163 QCOMPARE(selection.count(), 1);
164 QCOMPARE(selection.indexes().count(), 3);
165
166 // Verify that the visualRegionForSelection contains all visualRects.
167 // We do this indirectly using QRegion::boundingRect() because
168 // QRegion::contains(const QRect&) returns true even if the QRect is not
169 // entirely inside the QRegion.
170
171 const QRegion region = view.visualRegionForSelection(selection);
172 const QRect boundingRect = region.boundingRect();
173
174 QVERIFY(boundingRect.contains(view.visualRect(index0)));
175 QVERIFY(boundingRect.contains(view.visualRect(index1)));
176 QVERIFY(boundingRect.contains(view.visualRect(index2)));
177 }
178
179 QTEST_KDEMAIN(DolphinTreeViewTest, GUI)
180
181 #include "dolphintreeviewtest.moc"