┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
path: root/src/tests/dolphintreeviewtest.cpp
blob: 8e566a71954231816eff66326d3219b151d7e1f8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/***************************************************************************
 *   Copyright (C) 2010 by Frank Reininghaus ([email protected])    *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
 ***************************************************************************/

#include <qtest_kde.h>

#include "views/dolphintreeview.h"

#include <qtestkeyboard.h>
#include <qtestmouse.h>
#include <QtGui/QStringListModel>

class DolphinTreeViewTest : public QObject
{
    Q_OBJECT

private slots:

    void bug201459_firstLetterAndThenShiftClickSelection();
    void bug218114_visualRegionForSelection();

};

/**
 * TestView is a simple view class derived from DolphinTreeView.
 * It makes sure that the visualRect for each index contains only the item text as
 * returned by QAbstractItemModel::data(...) for the role Qt::DisplayRole.
 *
 * We have to check that DolphinTreeView handles the case of visualRects with different widths
 * correctly because this is the case in DolphinDetailsView which is derived from DolphinTreeView.
 */

class TestView : public DolphinTreeView
{
    Q_OBJECT

public:

    TestView(QWidget* parent = 0) : DolphinTreeView(parent) {};
    ~TestView() {};

    QRect visualRect(const QModelIndex& index) const {
        QRect rect = DolphinTreeView::visualRect(index);

        const QStyleOptionViewItem option = viewOptions();
        const QFontMetrics fontMetrics(option.font);
        int width = option.decorationSize.width() + fontMetrics.width(model()->data(index).toString());

        rect.setWidth(width);
        return rect;
    }

};

/**
 * When the first letter of a file name is pressed, this file becomes the current item
 * and gets selected. If the user then Shift-clicks another item, it is expected that
 * all items between these two items get selected. Before the bug
 *
 * https://bugs.kde.org/show_bug.cgi?id=201459
 *
 * was fixed, this was not the case: the starting point for the Shift-selection was not
 * updated if an item was selected by pressing the first letter of the file name.
 */

void DolphinTreeViewTest::bug201459_firstLetterAndThenShiftClickSelection()
{
    QStringList items;
    items << "a" << "b" << "c" << "d" << "e";
    QStringListModel model(items);

    QModelIndex index[5];
    for (int i = 0; i < 5; i++) {
        index[i] = model.index(i, 0);
    }

    DolphinTreeView view;
    view.setModel(&model);
    view.setSelectionMode(QAbstractItemView::ExtendedSelection);
    view.resize(400, 400);
    view.show();
    QTest::qWaitForWindowShown(&view);

    QItemSelectionModel* selectionModel = view.selectionModel();
    QModelIndexList selectedIndexes = selectionModel->selectedIndexes();
    QCOMPARE(selectedIndexes.count(), 0);

    // Control-click item 0 ("a")
    QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, view.visualRect(index[0]).center());
    QCOMPARE(view.currentIndex(), index[0]);
    selectedIndexes = selectionModel->selectedIndexes();
    QCOMPARE(selectedIndexes.count(), 1);
    QVERIFY(selectedIndexes.contains(index[0]));

    // Press "c", such that item 2 ("c") should be the current one.
    QTest::keyClick(view.viewport(), Qt::Key_C);
    QCOMPARE(view.currentIndex(), index[2]);
    selectedIndexes = selectionModel->selectedIndexes();
    QCOMPARE(selectedIndexes.count(), 1);
    QVERIFY(selectedIndexes.contains(index[2]));

    // Now Shift-Click the last item ("e"). We expect that 3 items ("c", "d", "e") are selected.
    QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ShiftModifier, view.visualRect(index[4]).center());
    QCOMPARE(view.currentIndex(), index[4]);
    selectedIndexes = selectionModel->selectedIndexes();
    QCOMPARE(selectedIndexes.count(), 3);
    QVERIFY(selectedIndexes.contains(index[2]));
    QVERIFY(selectedIndexes.contains(index[3]));
    QVERIFY(selectedIndexes.contains(index[4]));
}

/**
 * QTreeView assumes implicitly that the width of each item's visualRect is the same. This leads to painting
 * problems in Dolphin if items with different widths are in one QItemSelectionRange, see
 *
 * https://bugs.kde.org/show_bug.cgi?id=218114
 *
 * To fix this, DolphinTreeView has a custom implementation of visualRegionForSelection(). The following
 * unit test checks that.
 */

void DolphinTreeViewTest::bug218114_visualRegionForSelection()
{
    QStringList items;
    items << "a" << "an item with a long name" << "a";
    QStringListModel model(items);

    QModelIndex index0 = model.index(0, 0);
    QModelIndex index1 = model.index(1, 0);
    QModelIndex index2 = model.index(2, 0);

    TestView view;
    view.setModel(&model);
    view.setSelectionMode(QAbstractItemView::ExtendedSelection);
    view.resize(400, 400);
    view.show();
    QTest::qWaitForWindowShown(&view);

    // First check that the width of index1 is larger than that of index0 and index2 (this triggers the bug).

    QVERIFY(view.visualRect(index0).width() < view.visualRect(index1).width());
    QVERIFY(view.visualRect(index2).width() < view.visualRect(index1).width());

    // Select all items in one go.

    view.selectAll();
    const QItemSelection selection = view.selectionModel()->selection();
    QCOMPARE(selection.count(), 1);
    QCOMPARE(selection.indexes().count(), 3);

    // Verify that the visualRegionForSelection contains all visualRects.
    // We do this indirectly using QRegion::boundingRect() because
    // QRegion::contains(const QRect&) returns true even if the QRect is not
    // entirely inside the QRegion.

    const QRegion region = view.visualRegionForSelection(selection);
    const QRect boundingRect = region.boundingRect();

    QVERIFY(boundingRect.contains(view.visualRect(index0)));
    QVERIFY(boundingRect.contains(view.visualRect(index1)));
    QVERIFY(boundingRect.contains(view.visualRect(index2)));
}

QTEST_KDEMAIN(DolphinTreeViewTest, GUI)

#include "dolphintreeviewtest.moc"