diff options
Diffstat (limited to 'tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp')
-rw-r--r-- | tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp | 220 |
1 files changed, 131 insertions, 89 deletions
diff --git a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp index c05c72213a..6ebf255f31 100644 --- a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> @@ -38,7 +13,7 @@ #include <qsharedpointer.h> #include <qfiledialog.h> #include <qabstractitemdelegate.h> -#include <qitemdelegate.h> +#include <qstyleditemdelegate.h> #include <qlistview.h> #include <qcombobox.h> #include <qpushbutton.h> @@ -63,6 +38,8 @@ #include <QFileDialog> #include <QFileSystemModel> +#include <QtWidgets/private/qapplication_p.h> + #if defined(Q_OS_UNIX) #include <unistd.h> // for pathconf() on OS X #ifdef QT_BUILD_INTERNAL @@ -151,9 +128,10 @@ private slots: void QTBUG49600_nativeIconProviderCrash(); void focusObjectDuringDestruction(); - // NOTE: Please keep widgetlessNativeDialog() as the LAST test! + // NOTE: Please keep widgetlessNativeDialog() and + // hideNativeByDestruction() as the LAST tests! // - // widgetlessNativeDialog() is the only test function that creates + // widgetlessNativeDialog() are the only test functions that create // a native file dialog instance. GTK+ versions prior 3.15.5 have // a nasty bug (https://bugzilla.gnome.org/show_bug.cgi?id=725164) // in GtkFileChooserWidget, which makes it leak its folder change @@ -164,6 +142,7 @@ private slots: // The crash has been fixed in GTK+ 3.15.5, but the RHEL 7.2 CI has // GTK+ 3.14.13 installed (QTBUG-55276). void widgetlessNativeDialog(); + void hideNativeByDestruction(); private: void cleanupSettingsFile(); @@ -231,7 +210,7 @@ void tst_QFiledialog::currentChangedSignal() QVERIFY(listView->model()->hasChildren(folder)); listView->setCurrentIndex(folder); - QCOMPARE(spyCurrentChanged.count(), 1); + QCOMPARE(spyCurrentChanged.size(), 1); } // only emitted from the views, sidebar, or lookin combo @@ -253,7 +232,7 @@ void tst_QFiledialog::directoryEnteredSignal() QVERIFY(secondItem.isValid()); sidebar->setCurrentIndex(secondItem); QTest::keyPress(sidebar->viewport(), Qt::Key_Return); - QCOMPARE(spyDirectoryEntered.count(), 1); + QCOMPARE(spyDirectoryEntered.size(), 1); spyDirectoryEntered.clear(); // lookInCombo @@ -262,7 +241,7 @@ void tst_QFiledialog::directoryEnteredSignal() QVERIFY(comboBox->view()->model()->index(1, 0).isValid()); comboBox->view()->setCurrentIndex(comboBox->view()->model()->index(1, 0)); QTest::keyPress(comboBox->view()->viewport(), Qt::Key_Return); - QCOMPARE(spyDirectoryEntered.count(), 1); + QCOMPARE(spyDirectoryEntered.size(), 1); spyDirectoryEntered.clear(); // view @@ -339,7 +318,7 @@ void tst_QFiledialog::filesSelectedSignal() QVERIFY(button->isEnabled()); button->animateClick(); QTRY_COMPARE(fd.isVisible(), false); - QCOMPARE(spyFilesSelected.count(), 1); + QCOMPARE(spyFilesSelected.size(), 1); } // only emitted when the combo box is activated @@ -364,7 +343,7 @@ void tst_QFiledialog::filterSelectedSignal() QTest::keyPress(filters, Qt::Key_Down); - QCOMPARE(spyFilterSelected.count(), 1); + QCOMPARE(spyFilterSelected.size(), 1); } void tst_QFiledialog::args() @@ -405,14 +384,14 @@ void tst_QFiledialog::directory() #ifndef Q_OS_WIN QCOMPARE(tempPath, fd.directory().absolutePath()); #endif - QCOMPARE(spyCurrentChanged.count(), 0); - QCOMPARE(spyDirectoryEntered.count(), 0); - QCOMPARE(spyFilesSelected.count(), 0); - QCOMPARE(spyFilterSelected.count(), 0); + QCOMPARE(spyCurrentChanged.size(), 0); + QCOMPARE(spyDirectoryEntered.size(), 0); + QCOMPARE(spyFilesSelected.size(), 0); + QCOMPARE(spyFilterSelected.size(), 0); // Check my way QList<QListView*> list = fd.findChildren<QListView*>("listView"); - QVERIFY(list.count() > 0); + QVERIFY(list.size() > 0); #ifdef Q_OS_WIN QCOMPARE(list.at(0)->rootIndex().data().toString().toLower(), temp.dirName().toLower()); #else @@ -443,7 +422,14 @@ void tst_QFiledialog::completer_data() QTest::newRow("goto root") << QString() << rootPath << -1; QTest::newRow("start at root") << rootPath << QString() << -1; - QFileInfoList list = QDir::root().entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); + QDir dir = QDir::root(); +#ifdef Q_OS_ANDROID + const auto homePaths = QStandardPaths::standardLocations(QStandardPaths::HomeLocation); + QVERIFY(!homePaths.isEmpty()); + dir = QDir(homePaths.first()); +#endif + + QFileInfoList list = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); QVERIFY(!list.isEmpty()); const QString folder = list.first().absoluteFilePath(); QTest::newRow("start at one below root r") << folder << "r" << -1; @@ -530,10 +516,9 @@ void tst_QFiledialog::completer() } // press 'keys' for the input - for (int i = 0; i < input.count(); ++i) + for (int i = 0; i < input.size(); ++i) QTest::keyPress(lineEdit, input[i].toLatin1()); - QStringList expectedFiles; if (expected == -1) { QString fullPath = startPath; if (!fullPath.endsWith(QLatin1Char('/'))) @@ -546,11 +531,11 @@ void tst_QFiledialog::completer() QFileInfo fi(fullPath); QDir x(fi.absolutePath()); - expectedFiles = x.entryList(model->filter()); + const QStringList expectedFiles = x.entryList(model->filter()); expected = 0; if (input.startsWith("..")) input.clear(); - foreach (const QString &expectedFile, expectedFiles) { + for (const QString &expectedFile : expectedFiles) { if (expectedFile.startsWith(input, caseSensitivity)) ++expected; } @@ -586,16 +571,16 @@ void tst_QFiledialog::completer_up() fd.show(); QLineEdit *lineEdit = fd.findChild<QLineEdit*>("fileNameEdit"); QVERIFY(lineEdit); - QCOMPARE(spyFilesSelected.count(), 0); - int depth = QDir::currentPath().split('/').count(); + QCOMPARE(spyFilesSelected.size(), 0); + int depth = QDir::currentPath().split('/').size(); for (int i = 0; i <= depth * 3 + 1; ++i) { lineEdit->insert("../"); qApp->processEvents(); } - QCOMPARE(spyCurrentChanged.count(), 0); - QCOMPARE(spyDirectoryEntered.count(), 0); - QCOMPARE(spyFilesSelected.count(), 0); - QCOMPARE(spyFilterSelected.count(), 0); + QCOMPARE(spyCurrentChanged.size(), 0); + QCOMPARE(spyDirectoryEntered.size(), 0); + QCOMPARE(spyFilesSelected.size(), 0); + QCOMPARE(spyFilterSelected.size(), 0); } void tst_QFiledialog::acceptMode() @@ -675,7 +660,7 @@ void tst_QFiledialog::filters() // effects QList<QComboBox*> views = fd.findChildren<QComboBox*>("fileTypeCombo"); - QCOMPARE(views.count(), 1); + QCOMPARE(views.size(), 1); QCOMPARE(views.at(0)->isVisible(), false); QStringList filters; @@ -690,15 +675,15 @@ void tst_QFiledialog::filters() QCOMPARE(fd.nameFilters(), filters); fd.setNameFilter("Image files (*.png *.xpm *.jpg);;Text files (*.txt);;Any files (*.*)"); QCOMPARE(fd.nameFilters(), filters); - QCOMPARE(spyCurrentChanged.count(), 0); - QCOMPARE(spyDirectoryEntered.count(), 0); - QCOMPARE(spyFilesSelected.count(), 0); - QCOMPARE(spyFilterSelected.count(), 0); + QCOMPARE(spyCurrentChanged.size(), 0); + QCOMPARE(spyDirectoryEntered.size(), 0); + QCOMPARE(spyFilesSelected.size(), 0); + QCOMPARE(spyFilterSelected.size(), 0); // setting shouldn't emit any signals for (int i = views.at(0)->currentIndex(); i < views.at(0)->count(); ++i) views.at(0)->setCurrentIndex(i); - QCOMPARE(spyFilterSelected.count(), 0); + QCOMPARE(spyFilterSelected.size(), 0); //Let check if filters with whitespaces QFileDialog fd2; @@ -737,7 +722,7 @@ void tst_QFiledialog::selectFilter() QCOMPARE(fd.selectedNameFilter(), filters.at(2)); fd.selectNameFilter(""); QCOMPARE(fd.selectedNameFilter(), filters.at(2)); - QCOMPARE(spyFilterSelected.count(), 0); + QCOMPARE(spyFilterSelected.size(), 0); } void tst_QFiledialog::history() @@ -776,10 +761,10 @@ void tst_QFiledialog::history() badHistory << QDir::toNativeSeparators(QDir::current().absolutePath()); QCOMPARE(fd.history(), badHistory); - QCOMPARE(spyCurrentChanged.count(), 0); - QCOMPARE(spyDirectoryEntered.count(), 0); - QCOMPARE(spyFilesSelected.count(), 0); - QCOMPARE(spyFilterSelected.count(), 0); + QCOMPARE(spyCurrentChanged.size(), 0); + QCOMPARE(spyDirectoryEntered.size(), 0); + QCOMPARE(spyFilesSelected.size(), 0); + QCOMPARE(spyFilterSelected.size(), 0); } void tst_QFiledialog::iconProvider() @@ -821,7 +806,7 @@ void tst_QFiledialog::itemDelegate() { QFileDialog fd; QVERIFY(fd.itemDelegate() != 0); - QItemDelegate *id = new QItemDelegate(&fd); + QStyledItemDelegate *id = new QStyledItemDelegate(&fd); fd.setItemDelegate(id); QCOMPARE(fd.itemDelegate(), (QAbstractItemDelegate *)id); } @@ -882,7 +867,7 @@ void tst_QFiledialog::selectFile() QVERIFY(model); fd->setDirectory(QDir::currentPath()); // default value - QCOMPARE(fd->selectedFiles().count(), 1); + QCOMPARE(fd->selectedFiles().size(), 1); QScopedPointer<QTemporaryFile> tempFile; if (file == QLatin1String("temp")) { @@ -892,7 +877,7 @@ void tst_QFiledialog::selectFile() } fd->selectFile(file); - QCOMPARE(fd->selectedFiles().count(), count); + QCOMPARE(fd->selectedFiles().size(), count); if (tempFile.isNull()) { QCOMPARE(model->index(fd->directory().path()), model->index(QDir::currentPath())); } else { @@ -940,7 +925,7 @@ void tst_QFiledialog::selectFiles() QString filesPath = fd.directory().absolutePath(); for (int i=0; i < 5; ++i) { QFile file(filesPath + QLatin1String("/qfiledialog_auto_test_not_pres_") + QString::number(i)); - file.open(QIODevice::WriteOnly); + QVERIFY(file.open(QIODevice::WriteOnly)); file.resize(1024); file.flush(); file.close(); @@ -949,29 +934,29 @@ void tst_QFiledialog::selectFiles() // Get a list of files in the view and then get the corresponding index's QStringList list = fd.directory().entryList(QDir::Files); QModelIndexList toSelect; - QVERIFY(list.count() > 1); + QVERIFY(list.size() > 1); QListView* listView = fd.findChild<QListView*>("listView"); QVERIFY(listView); - for (int i = 0; i < list.count(); ++i) { + for (int i = 0; i < list.size(); ++i) { fd.selectFile(fd.directory().path() + QLatin1Char('/') + list.at(i)); QTRY_VERIFY(!listView->selectionModel()->selectedRows().isEmpty()); toSelect.append(listView->selectionModel()->selectedRows().last()); } - QCOMPARE(spyFilesSelected.count(), 0); + QCOMPARE(spyFilesSelected.size(), 0); listView->selectionModel()->clear(); - QCOMPARE(spyFilesSelected.count(), 0); + QCOMPARE(spyFilesSelected.size(), 0); // select the indexes - for (int i = 0; i < toSelect.count(); ++i) { + for (int i = 0; i < toSelect.size(); ++i) { listView->selectionModel()->select(toSelect.at(i), QItemSelectionModel::Select | QItemSelectionModel::Rows); } - QCOMPARE(fd.selectedFiles().count(), toSelect.count()); - QCOMPARE(spyCurrentChanged.count(), 0); - QCOMPARE(spyDirectoryEntered.count(), 0); - QCOMPARE(spyFilesSelected.count(), 0); - QCOMPARE(spyFilterSelected.count(), 0); + QCOMPARE(fd.selectedFiles().size(), toSelect.size()); + QCOMPARE(spyCurrentChanged.size(), 0); + QCOMPARE(spyDirectoryEntered.size(), 0); + QCOMPARE(spyFilesSelected.size(), 0); + QCOMPARE(spyFilterSelected.size(), 0); } @@ -997,13 +982,13 @@ void tst_QFiledialog::viewMode() // find widgets QList<QTreeView*> treeView = fd.findChildren<QTreeView*>("treeView"); - QCOMPARE(treeView.count(), 1); + QCOMPARE(treeView.size(), 1); QList<QListView*> listView = fd.findChildren<QListView*>("listView"); - QCOMPARE(listView.count(), 1); + QCOMPARE(listView.size(), 1); QList<QToolButton*> listButton = fd.findChildren<QToolButton*>("listModeButton"); - QCOMPARE(listButton.count(), 1); + QCOMPARE(listButton.size(), 1); QList<QToolButton*> treeButton = fd.findChildren<QToolButton*>("detailModeButton"); - QCOMPARE(treeButton.count(), 1); + QCOMPARE(treeButton.size(), 1); // default value QCOMPARE(fd.viewMode(), QFileDialog::List); @@ -1132,7 +1117,6 @@ void tst_QFiledialog::focus() QFileDialog fd; fd.setDirectory(QDir::currentPath()); fd.show(); - QApplication::setActiveWindow(&fd); QVERIFY(QTest::qWaitForWindowActive(&fd)); QCOMPARE(fd.isVisible(), true); QCOMPARE(QApplication::activeWindow(), static_cast<QWidget*>(&fd)); @@ -1142,7 +1126,7 @@ void tst_QFiledialog::focus() QCursor::setPos(fd.geometry().center()); QList<QWidget*> treeView = fd.findChildren<QWidget*>("fileNameEdit"); - QCOMPARE(treeView.count(), 1); + QCOMPARE(treeView.size(), 1); QVERIFY(treeView.at(0)); QTRY_COMPARE(treeView.at(0)->hasFocus(), true); QCOMPARE(treeView.at(0)->hasFocus(), true); @@ -1172,13 +1156,13 @@ void tst_QFiledialog::historyBack() QCOMPARE(backButton->isEnabled(), true); QCOMPARE(forwardButton->isEnabled(), false); fd.setDirectory(desktop); - QCOMPARE(spy.count(), 2); + QCOMPARE(spy.size(), 2); backButton->click(); qApp->processEvents(); QCOMPARE(backButton->isEnabled(), true); QCOMPARE(forwardButton->isEnabled(), true); - QCOMPARE(spy.count(), 3); + QCOMPARE(spy.size(), 3); QString currentPath = qvariant_cast<QString>(spy.last().first()); QCOMPARE(model->index(currentPath), model->index(temp)); @@ -1187,11 +1171,11 @@ void tst_QFiledialog::historyBack() QCOMPARE(currentPath, home); QCOMPARE(backButton->isEnabled(), false); QCOMPARE(forwardButton->isEnabled(), true); - QCOMPARE(spy.count(), 4); + QCOMPARE(spy.size(), 4); // nothing should change at this point backButton->click(); - QCOMPARE(spy.count(), 4); + QCOMPARE(spy.size(), 4); QCOMPARE(backButton->isEnabled(), false); QCOMPARE(forwardButton->isEnabled(), true); } @@ -1225,7 +1209,7 @@ void tst_QFiledialog::historyForward() QCOMPARE(model->index(qvariant_cast<QString>(spy.last().first())), model->index(desktop)); QCOMPARE(backButton->isEnabled(), true); QCOMPARE(forwardButton->isEnabled(), false); - QCOMPARE(spy.count(), 4); + QCOMPARE(spy.size(), 4); backButton->click(); QCOMPARE(model->index(qvariant_cast<QString>(spy.last().first())), model->index(temp)); @@ -1235,13 +1219,13 @@ void tst_QFiledialog::historyForward() QCOMPARE(model->index(qvariant_cast<QString>(spy.last().first())), model->index(home)); QCOMPARE(backButton->isEnabled(), false); QCOMPARE(forwardButton->isEnabled(), true); - QCOMPARE(spy.count(), 6); + QCOMPARE(spy.size(), 6); forwardButton->click(); QCOMPARE(model->index(qvariant_cast<QString>(spy.last().first())), model->index(temp)); backButton->click(); QCOMPARE(model->index(qvariant_cast<QString>(spy.last().first())), model->index(home)); - QCOMPARE(spy.count(), 8); + QCOMPARE(spy.size(), 8); forwardButton->click(); QCOMPARE(model->index(qvariant_cast<QString>(spy.last().first())), model->index(temp)); @@ -1452,6 +1436,10 @@ void tst_QFiledialog::widgetlessNativeDialog() { if (!QGuiApplicationPrivate::platformTheme()->usePlatformNativeDialog(QPlatformTheme::FileDialog)) QSKIP("This platform always uses widgets to realize its QFileDialog, instead of the native file dialog."); +#ifdef Q_OS_ANDROID + // QTBUG-101194 + QSKIP("Android: This keeps the window open. Figure out why."); +#endif QApplication::setAttribute(Qt::AA_DontUseNativeDialogs, false); QFileDialog fd; fd.setWindowModality(Qt::ApplicationModal); @@ -1464,6 +1452,46 @@ void tst_QFiledialog::widgetlessNativeDialog() QApplication::setAttribute(Qt::AA_DontUseNativeDialogs, true); } +void tst_QFiledialog::hideNativeByDestruction() +{ + if (!QGuiApplicationPrivate::platformTheme()->usePlatformNativeDialog(QPlatformTheme::FileDialog)) + QSKIP("This platform always uses widgets to realize its QFileDialog, instead of the native file dialog."); + +#ifdef Q_OS_ANDROID + // QTBUG-101194 + QSKIP("Android: This keeps the native window open. Figure out why."); +#endif + + QApplication::setAttribute(Qt::AA_DontUseNativeDialogs, false); + auto resetAttribute = qScopeGuard([]{ + QApplication::setAttribute(Qt::AA_DontUseNativeDialogs, true); + }); + + QWidget window; + QWidget *child = new QWidget(&window); + QPointer<QFileDialog> dialog = new QFileDialog(child); + // Make it application modal so that we don't end up with a sheet on macOS + dialog->setWindowModality(Qt::ApplicationModal); + window.show(); + QVERIFY(QTest::qWaitForWindowActive(&window)); + dialog->open(); + + // We test that the dialog opens and closes by watching the activation of the + // transient parent window. If it doesn't deactivate, then we have to skip. + const auto windowActive = [&window]{ return window.isActiveWindow(); }; + const auto windowInactive = [&window]{ return !window.isActiveWindow(); }; + if (!QTest::qWaitFor(windowInactive, 2000)) + QSKIP("Dialog didn't activate"); + + // This should destroy the dialog and close the native window + child->deleteLater(); + QTRY_VERIFY(!dialog); + // If the native window is still open, then the transient parent can't become + // active + window.activateWindow(); + QVERIFY(QTest::qWaitFor(windowActive, 2000)); +} + void tst_QFiledialog::selectedFilesWithoutWidgets() { // Test for a crash when widgets are not instantiated yet. @@ -1568,6 +1596,10 @@ void tst_QFiledialog::rejectModalDialogs() { if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: This freezes. Figure out why."); +#ifdef Q_OS_ANDROID + // QTBUG-101194 + QSKIP("Android: This freezes. Figure out why."); +#endif // QTBUG-38672 , static functions should return empty Urls DialogRejecter dr; @@ -1599,6 +1631,12 @@ void tst_QFiledialog::QTBUG49600_nativeIconProviderCrash() { if (!QGuiApplicationPrivate::platformTheme()->usePlatformNativeDialog(QPlatformTheme::FileDialog)) QSKIP("This platform always uses widgets to realize its QFileDialog, instead of the native file dialog."); + +#ifdef Q_OS_ANDROID + // QTBUG-101194 + QSKIP("Android: This hangs. Figure out why."); +#endif + QFileDialog fd; fd.iconProvider(); } @@ -1630,6 +1668,10 @@ void tst_QFiledialog::focusObjectDuringDestruction() { if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: This freezes. Figure out why."); +#ifdef Q_OS_ANDROID + // QTBUG-101194 + QSKIP("Android: This freezes. Figure out why."); +#endif QTRY_VERIFY(QGuiApplication::topLevelWindows().isEmpty()); |