]>
cloud.milkyroute.net Git - dolphin.git/blob - src/tests/dolphinviewtest_allviewmodes.cpp
1 /****************************************************************************
2 * Copyright (C) 2010-2011 by Frank Reininghaus (frank78ac@googlemail.com) *
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. *
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. *
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 *****************************************************************************/
22 #include "dolphinviewtest_allviewmodes.h"
24 #include <qtest_kde.h>
28 #include "views/dolphinview.h"
29 #include "views/dolphinmodel.h"
30 #include "views/dolphindirlister.h"
31 #include "views/dolphinsortfilterproxymodel.h"
32 #include "views/zoomlevelinfo.h"
36 #include <qtestmouse.h>
37 #include <qtestkeyboard.h>
39 DolphinViewTest_AllViewModes::DolphinViewTest_AllViewModes() {
40 // Need to register KFileItemList for use with QSignalSpy
41 qRegisterMetaType
<KFileItemList
>("KFileItemList");
45 * testSelection() checks the basic selection functionality of DolphinView, including:
48 * selectedItemsCount()
54 * and the signal selectionChanged(const KFileItemList& selection)
57 Q_DECLARE_METATYPE(KFileItemList
)
59 void DolphinViewTest_AllViewModes::testSelection() {
61 const int totalItems
= 50;
62 for (int i
= 0; i
< totalItems
; i
++) {
63 dir
.createFile(QString("%1").arg(i
));
66 DolphinView
view(dir
.url(), 0);
67 QAbstractItemView
* itemView
= initView(&view
);
69 // Start with an empty selection
70 view
.clearSelection();
72 QCOMPARE(view
.selectedItems().count(), 0);
73 QCOMPARE(view
.selectedItemsCount(), 0);
74 QVERIFY(!view
.hasSelection());
76 // First some simple tests where either all or no items are selected
78 verifySelectedItemsCount(&view
, totalItems
);
80 view
.invertSelection();
81 verifySelectedItemsCount(&view
, 0);
83 view
.invertSelection();
84 verifySelectedItemsCount(&view
, totalItems
);
86 view
.clearSelection();
87 verifySelectedItemsCount(&view
, 0);
89 // Now we select individual items using mouse clicks
90 QModelIndex index
= itemView
->model()->index(2, 0);
91 itemView
->scrollTo(index
);
92 QTest::mouseClick(itemView
->viewport(), Qt::LeftButton
, Qt::ControlModifier
, itemView
->visualRect(index
).center());
93 verifySelectedItemsCount(&view
, 1);
95 index
= itemView
->model()->index(totalItems
- 5, 0);
96 itemView
->scrollTo(index
);
97 QTest::mouseClick(itemView
->viewport(), Qt::LeftButton
, Qt::ControlModifier
, itemView
->visualRect(index
).center());
98 verifySelectedItemsCount(&view
, 2);
100 index
= itemView
->model()->index(totalItems
- 2, 0);
101 itemView
->scrollTo(index
);
102 QTest::mouseClick(itemView
->viewport(), Qt::LeftButton
, Qt::ShiftModifier
, itemView
->visualRect(index
).center());
103 verifySelectedItemsCount(&view
, 5);
105 view
.invertSelection();
106 verifySelectedItemsCount(&view
, totalItems
- 5);
108 // Pressing Esc should clear the selection
109 QTest::keyClick(itemView
->viewport(), Qt::Key_Escape
);
110 verifySelectedItemsCount(&view
, 0);
114 * Check that setting the directory view properties works.
117 void DolphinViewTest_AllViewModes::testViewPropertySettings()
119 // Create some files with different sizes and modification times to check the different sorting options
120 QDateTime now
= QDateTime::currentDateTime();
123 dir
.createFile("a", "A file", now
.addDays(-3));
124 dir
.createFile("b", "A larger file", now
.addDays(0));
125 dir
.createDir("c", now
.addDays(-2));
126 dir
.createFile("d", "The largest file in this directory", now
.addDays(-1));
127 dir
.createFile("e", "An even larger file", now
.addDays(-4));
128 dir
.createFile(".f");
130 DolphinView
view(dir
.url(), 0);
133 // First set all settings to the default.
134 view
.setSorting(DolphinView::SortByName
);
135 QCOMPARE(view
.sorting(), DolphinView::SortByName
);
137 view
.setSortOrder(Qt::AscendingOrder
);
138 QCOMPARE(view
.sortOrder(), Qt::AscendingOrder
);
140 view
.setSortFoldersFirst(true);
141 QVERIFY(view
.sortFoldersFirst());
143 view
.setShowPreview(false);
144 QVERIFY(!view
.showPreview());
146 view
.setShowHiddenFiles(false);
147 QVERIFY(!view
.showHiddenFiles());
149 /** Check that the sort order is correct for different kinds of settings */
151 // Sort by Name, ascending
152 QCOMPARE(view
.sorting(), DolphinView::SortByName
);
153 QCOMPARE(view
.sortOrder(), Qt::AscendingOrder
);
154 QCOMPARE(viewItems(&view
), QStringList() << "c" << "a" << "b" << "d" << "e");
156 // Sort by Name, descending
157 view
.setSortOrder(Qt::DescendingOrder
);
158 QCOMPARE(view
.sorting(), DolphinView::SortByName
);
159 QCOMPARE(view
.sortOrder(), Qt::DescendingOrder
);
160 QCOMPARE(viewItems(&view
), QStringList() << "c" << "e" << "d" << "b" << "a");
162 // Sort by Size, descending
163 view
.setSorting(DolphinView::SortBySize
);
164 QCOMPARE(view
.sorting(), DolphinView::SortBySize
);
165 QCOMPARE(view
.sortOrder(), Qt::DescendingOrder
);
166 QCOMPARE(viewItems(&view
), QStringList() << "c" << "d" << "e" << "b" << "a");
168 // Sort by Size, ascending
169 view
.setSortOrder(Qt::AscendingOrder
);
170 QCOMPARE(view
.sorting(), DolphinView::SortBySize
);
171 QCOMPARE(view
.sortOrder(), Qt::AscendingOrder
);
172 QCOMPARE(viewItems(&view
), QStringList() << "c" << "a" << "b" << "e" << "d");
174 // Sort by Date, ascending
175 view
.setSorting(DolphinView::SortByDate
);
176 QCOMPARE(view
.sorting(), DolphinView::SortByDate
);
177 QCOMPARE(view
.sortOrder(), Qt::AscendingOrder
);
178 QCOMPARE(viewItems(&view
), QStringList() << "c" << "e" << "a" << "d" << "b");
180 // Sort by Date, descending
181 view
.setSortOrder(Qt::DescendingOrder
);
182 QCOMPARE(view
.sorting(), DolphinView::SortByDate
);
183 QCOMPARE(view
.sortOrder(), Qt::DescendingOrder
);
184 QCOMPARE(viewItems(&view
), QStringList() << "c" << "b" << "d" << "a" << "e");
186 // Disable "Sort Folders First"
187 view
.setSortFoldersFirst(false);
188 QVERIFY(!view
.sortFoldersFirst());
189 QCOMPARE(viewItems(&view
), QStringList()<< "b" << "d" << "c" << "a" << "e");
191 // Try again with Sort by Name, ascending
192 view
.setSorting(DolphinView::SortByName
);
193 view
.setSortOrder(Qt::AscendingOrder
);
194 QCOMPARE(view
.sorting(), DolphinView::SortByName
);
195 QCOMPARE(view
.sortOrder(), Qt::AscendingOrder
);
196 QCOMPARE(viewItems(&view
), QStringList() << "a" << "b" << "c" << "d" << "e");
198 // Show hidden files. This triggers the dir lister
199 // -> we have to wait until loading the hidden files is finished
200 view
.setShowHiddenFiles(true);
201 QVERIFY(waitForFinishedPathLoading(&view
));
202 QVERIFY(view
.showHiddenFiles());
203 QCOMPARE(viewItems(&view
), QStringList() << ".f" << "a" << "b" << "c" << "d" << "e");
206 view
.setShowPreview(true);
207 QVERIFY(view
.showPreview());
209 // TODO: Check that the view properties are restored correctly when changing the folder and then going back.
213 * testZoomLevel() checks that setting the zoom level works, both using DolphinView's API and using Ctrl+mouse wheel.
216 void DolphinViewTest_AllViewModes::testZoomLevel()
219 dir
.createFiles(QStringList() << "a" << "b");
220 DolphinView
view(dir
.url(), 0);
221 QAbstractItemView
* itemView
= initView(&view
);
223 view
.setShowPreview(false);
224 QVERIFY(!view
.showPreview());
226 int zoomLevelBackup
= view
.zoomLevel();
228 int zoomLevel
= ZoomLevelInfo::minimumLevel();
229 view
.setZoomLevel(zoomLevel
);
230 QCOMPARE(view
.zoomLevel(), zoomLevel
);
232 // Increase the zoom level successively to the maximum.
233 while(zoomLevel
< ZoomLevelInfo::maximumLevel()) {
235 view
.setZoomLevel(zoomLevel
);
236 QCOMPARE(view
.zoomLevel(), zoomLevel
);
239 // Try setting a zoom level larger than the maximum
240 view
.setZoomLevel(ZoomLevelInfo::maximumLevel() + 1);
241 QCOMPARE(view
.zoomLevel(), ZoomLevelInfo::maximumLevel());
243 // Turn previews on and try setting a zoom level smaller than the minimum
244 view
.setShowPreview(true);
245 QVERIFY(view
.showPreview());
246 view
.setZoomLevel(ZoomLevelInfo::minimumLevel() - 1);
247 QCOMPARE(view
.zoomLevel(), ZoomLevelInfo::minimumLevel());
249 // Turn previews off again and check that the zoom level is restored
250 view
.setShowPreview(false);
251 QVERIFY(!view
.showPreview());
252 QCOMPARE(view
.zoomLevel(), ZoomLevelInfo::maximumLevel());
254 // Change the zoom level using Ctrl+mouse wheel
255 QModelIndex index
= itemView
->model()->index(0, 0);
256 itemView
->scrollTo(index
);
258 while (view
.zoomLevel() > ZoomLevelInfo::minimumLevel()) {
259 int oldZoomLevel
= view
.zoomLevel();
260 QWheelEvent
wheelEvent(itemView
->visualRect(index
).center(), -1, Qt::NoButton
, Qt::ControlModifier
);
261 bool wheelEventReceived
= qApp
->notify(itemView
->viewport(), &wheelEvent
);
262 QVERIFY(wheelEventReceived
);
263 QVERIFY(view
.zoomLevel() < oldZoomLevel
);
265 QCOMPARE(view
.zoomLevel(), ZoomLevelInfo::minimumLevel());
267 while (view
.zoomLevel() < ZoomLevelInfo::maximumLevel()) {
268 int oldZoomLevel
= view
.zoomLevel();
269 QWheelEvent
wheelEvent(itemView
->visualRect(index
).center(), 1, Qt::NoButton
, Qt::ControlModifier
);
270 bool wheelEventReceived
= qApp
->notify(itemView
->viewport(), &wheelEvent
);
271 QVERIFY(wheelEventReceived
);
272 QVERIFY(view
.zoomLevel() > oldZoomLevel
);
274 QCOMPARE(view
.zoomLevel(), ZoomLevelInfo::maximumLevel());
276 // Turn previews on again and check that the zoom level is restored
277 view
.setShowPreview(true);
278 QVERIFY(view
.showPreview());
279 QCOMPARE(view
.zoomLevel(), ZoomLevelInfo::minimumLevel());
281 // Restore the initial state
282 view
.setZoomLevel(zoomLevelBackup
);
283 view
.setShowPreview(false);
284 view
.setZoomLevel(zoomLevelBackup
);
288 * testSaveAndRestoreState() checks if saving and restoring the view state (current item, scroll position).
290 * Note that we call qApp->sendPostedEvents() every time the view's finishedPathLoading(const KUrl&) signal
291 * is received. The reason is that the scroll position is restored in the slot restoreContentsPosition(),
292 * which is been invoked using a queued connection in DolphinView::slotLoadingCompleted(). To make sure
293 * that this slot is really executed before we proceed, we have to empty the event queue using qApp->sendPostedEvents().
296 void DolphinViewTest_AllViewModes::testSaveAndRestoreState()
298 const int totalItems
= 50;
300 for (int i
= 0; i
< totalItems
; i
++) {
301 dir
.createFile(QString("%1").arg(i
));
304 DolphinView
view(dir
.url(), 0);
307 // Set sorting settings to the default to make sure that the item positions are reproducible.
308 view
.setSorting(DolphinView::SortByName
);
309 QCOMPARE(view
.sorting(), DolphinView::SortByName
);
310 view
.setSortOrder(Qt::AscendingOrder
);
311 QCOMPARE(view
.sortOrder(), Qt::AscendingOrder
);
313 const QModelIndex index45
= itemView(&view
)->model()->index(45, 0);
314 itemView(&view
)->scrollTo(index45
);
315 itemView(&view
)->setCurrentIndex(index45
);
316 const int scrollPosX
= itemView(&view
)->horizontalScrollBar()->value();
317 const int scrollPosY
= itemView(&view
)->verticalScrollBar()->value();
320 // Save the view state
321 QByteArray viewState
;
322 QDataStream
saveStream(&viewState
, QIODevice::WriteOnly
);
323 view
.saveState(saveStream
);
326 view
.setUrl(dir
.name() + "51");
327 QVERIFY(waitForFinishedPathLoading(&view
));
328 qApp
->sendPostedEvents();
330 // Go back, but do not call DolphinView::restoreState()
331 view
.setUrl(dir
.url());
332 QVERIFY(waitForFinishedPathLoading(&view
));
333 qApp
->sendPostedEvents();
335 // Verify that the view is scrolled to top-left corner and that item 45 is not the current item.
336 // Note that the vertical position of the columns view might not be zero -> skip that part
337 // of the check in this case.
338 QVERIFY(itemView(&view
)->currentIndex() != index45
);
339 QCOMPARE(itemView(&view
)->horizontalScrollBar()->value(), 0);
340 if (mode() != DolphinView::ColumnView
) {
341 QCOMPARE(itemView(&view
)->verticalScrollBar()->value(), 0);
344 // Change the URL again
345 view
.setUrl(dir
.name() + "51");
346 QVERIFY(waitForFinishedPathLoading(&view
));
347 qApp
->sendPostedEvents();
349 // Check that the current item and scroll position are correct if DolphinView::restoreState()
350 // is called after the URL change
351 view
.setUrl(dir
.url());
352 QDataStream
restoreStream(viewState
);
353 view
.restoreState(restoreStream
);
354 QVERIFY(waitForFinishedPathLoading(&view
));
355 qApp
->sendPostedEvents();
357 QCOMPARE(itemView(&view
)->currentIndex(), index45
);
358 QCOMPARE(itemView(&view
)->horizontalScrollBar()->value(), scrollPosX
);
359 QCOMPARE(itemView(&view
)->verticalScrollBar()->value(), scrollPosY
);
363 * testKeyboardFocus() checks whether a view grabs the keyboard focus.
365 * A view may never grab the keyboard focus itself and must respect the focus-state
366 * when switching the view mode, see
368 * https://bugs.kde.org/show_bug.cgi?id=261147
371 void DolphinViewTest_AllViewModes::testKeyboardFocus()
374 dir
.createFiles(QStringList() << "a" << "b");
375 DolphinView
view(dir
.url(), 0);
378 // Move the keyboard focus to another widget.
381 QTest::qWaitForWindowShown(&widget
);
384 QVERIFY(!view
.hasFocus());
386 // Switch view modes and verify that the view does not get the focus back
387 for (int i
= 0; i
<= DolphinView::MaxModeEnum
; ++i
) {
388 view
.setMode(static_cast<DolphinView::Mode
>(i
));
389 QVERIFY(!view
.hasFocus());
393 QAbstractItemView
* DolphinViewTest_AllViewModes::initView(DolphinView
* view
) const
395 view
->setMode(mode());
396 view
->resize(200, 300);
398 QTest::qWaitForWindowShown(view
);
399 Q_ASSERT(verifyCorrectViewMode(view
));
400 reloadViewAndWait(view
);
401 return itemView(view
);
405 * verifySelectedItemsCount(int) waits until the DolphinView's selectionChanged(const KFileItemList&)
406 * signal is received and checks that the selection state of the view is as expected.
409 void DolphinViewTest_AllViewModes::verifySelectedItemsCount(DolphinView
* view
, int itemsCount
) const
411 QSignalSpy
spySelectionChanged(view
, SIGNAL(selectionChanged(const KFileItemList
&)));
412 QVERIFY(QTest::kWaitForSignal(view
, SIGNAL(selectionChanged(const KFileItemList
&)), 500));
414 QCOMPARE(view
->selectedItems().count(), itemsCount
);
415 QCOMPARE(view
->selectedItemsCount(), itemsCount
);
416 QCOMPARE(spySelectionChanged
.count(), 1);
417 QCOMPARE(qvariant_cast
<KFileItemList
>(spySelectionChanged
.at(0).at(0)).count(), itemsCount
);
419 QVERIFY(view
->hasSelection());
422 QVERIFY(!view
->hasSelection());
426 #include "dolphinviewtest_allviewmodes.moc"