868 lines
40 KiB
C++
868 lines
40 KiB
C++
// Copyright (C) 2021 The Qt Company Ltd.
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
|
|
|
#include <QtTest/qtest.h>
|
|
#include <QtTest/qsignalspy.h>
|
|
#include <QtQml/qqmlfile.h>
|
|
#include <QtQuick/private/qquicklistview_p.h>
|
|
#include <QtQuickTest/quicktest.h>
|
|
#include <QtQuickControlsTestUtils/private/controlstestutils_p.h>
|
|
#include <QtQuickControlsTestUtils/private/dialogstestutils_p.h>
|
|
#include <QtQuickDialogs2/private/qquickfolderdialog_p.h>
|
|
#include <QtQuickDialogs2QuickImpl/private/qquickplatformfolderdialog_p.h>
|
|
#include <QtQuickDialogs2QuickImpl/private/qquickfiledialogdelegate_p.h>
|
|
#include <QtQuickDialogs2QuickImpl/private/qquickfolderbreadcrumbbar_p.h>
|
|
#include <QtQuickDialogs2QuickImpl/private/qquickfolderbreadcrumbbar_p_p.h>
|
|
#include <QtQuickDialogs2QuickImpl/private/qquickfolderdialogimpl_p.h>
|
|
#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h>
|
|
#include <QtQuickTemplates2/private/qquickcombobox_p.h>
|
|
#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p.h>
|
|
#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p_p.h>
|
|
#include <QtQuickTemplates2/private/qquicklabel_p.h>
|
|
#include <QtQuickTemplates2/private/qquickoverlay_p.h>
|
|
#include <QtQuickControls2/qquickstyle.h>
|
|
|
|
using namespace QQuickVisualTestUtils;
|
|
using namespace QQuickDialogTestUtils;
|
|
using namespace QQuickControlsTestUtils;
|
|
|
|
class tst_QQuickFolderDialogImpl : public QQmlDataTest
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
tst_QQuickFolderDialogImpl();
|
|
static void initMain()
|
|
{
|
|
// We need to set this attribute.
|
|
QCoreApplication::setAttribute(Qt::AA_DontUseNativeDialogs);
|
|
// We also don't want to run this for every style, as each one will have
|
|
// different ways of implementing the dialogs.
|
|
// For now we only test one style.
|
|
QQuickStyle::setStyle("Basic");
|
|
}
|
|
|
|
private slots:
|
|
void initTestCase() override;
|
|
void cleanupTestCase();
|
|
|
|
void defaults();
|
|
void chooseFolderViaStandardButtons();
|
|
void bindCurrentFolder_data();
|
|
void bindCurrentFolder();
|
|
void changeFolderViaDoubleClick();
|
|
void changeFolderViaTextEdit();
|
|
void changeFolderViaEnter();
|
|
void cancelDialogWhileTextEditHasFocus();
|
|
void goUp();
|
|
void goUpWhileTextEditHasFocus();
|
|
void goIntoLargeFolder();
|
|
void clickOnBreadcrumb();
|
|
void keyAndShortcutHandling();
|
|
void tabFocusNavigation();
|
|
void acceptRejectLabel();
|
|
void bindTitle();
|
|
void itemsDisabledWhenNecessary();
|
|
void done_data();
|
|
void done();
|
|
|
|
private:
|
|
QTemporaryDir tempDir;
|
|
QScopedPointer<QFile> tempFile1;
|
|
QScopedPointer<QFile> tempFile2;
|
|
QDir tempSubDir1;
|
|
QDir tempSubSubDir;
|
|
QScopedPointer<QFile> tempSubFile1;
|
|
QScopedPointer<QFile> tempSubFile2;
|
|
QDir tempSubDir2;
|
|
QDir oldCurrentDir;
|
|
};
|
|
|
|
tst_QQuickFolderDialogImpl::tst_QQuickFolderDialogImpl()
|
|
: QQmlDataTest(QT_QMLTEST_DATADIR)
|
|
{
|
|
}
|
|
|
|
void tst_QQuickFolderDialogImpl::initTestCase()
|
|
{
|
|
QQmlDataTest::initTestCase();
|
|
|
|
QVERIFY(tempDir.isValid());
|
|
// QTEST_QUICKCONTROLS_MAIN constructs the test case object once,
|
|
// and then calls qRun() for each style, and qRun() calls initTestCase().
|
|
// So, we need to check if we've already made the temporary directory.
|
|
// Note that this is only necessary if the test is run with more than one style.
|
|
if (!QDir(tempDir.path()).isEmpty())
|
|
return;
|
|
|
|
/*
|
|
Create a couple of files within the temporary directory. The structure is:
|
|
|
|
[temp directory]
|
|
├── sub-dir-1
|
|
│ ├── sub-sub-dir
|
|
│ ├── sub-file1.txt
|
|
│ └── sub-file2.txt
|
|
├── sub-dir-2
|
|
├── file1.txt
|
|
└── file2.txt
|
|
*/
|
|
tempSubDir1 = QDir(tempDir.path());
|
|
QVERIFY2(tempSubDir1.mkdir("sub-dir-1"), qPrintable(QString::fromLatin1(
|
|
"Failed to make sub-directory \"sub-dir-1\" in %1. Permissions are: %2")
|
|
.arg(tempDir.path(), QDebug::toString(QFileInfo(tempDir.path()).permissions()))));
|
|
QVERIFY(tempSubDir1.cd("sub-dir-1"));
|
|
|
|
tempSubSubDir = QDir(tempSubDir1.path());
|
|
QVERIFY2(tempSubSubDir.mkdir("sub-sub-dir"), qPrintable(QString::fromLatin1(
|
|
"Failed to make sub-directory \"sub-sub-dir\" in %1. Permissions are: %2")
|
|
.arg(tempSubDir1.path(), QDebug::toString(QFileInfo(tempSubDir1.path()).permissions()))));
|
|
QVERIFY(tempSubSubDir.cd("sub-sub-dir"));
|
|
|
|
tempSubFile1.reset(new QFile(tempSubDir1.path() + "/sub-file1.txt"));
|
|
QVERIFY(tempSubFile1->open(QIODevice::ReadWrite));
|
|
|
|
tempSubFile2.reset(new QFile(tempSubDir1.path() + "/sub-file2.txt"));
|
|
QVERIFY(tempSubFile2->open(QIODevice::ReadWrite));
|
|
|
|
tempSubDir2 = QDir(tempDir.path());
|
|
QVERIFY2(tempSubDir2.mkdir("sub-dir-2"), qPrintable(QString::fromLatin1(
|
|
"Failed to make sub-directory \"sub-dir-2\" in %1. Permissions are: %2")
|
|
.arg(tempDir.path(), QDebug::toString(QFileInfo(tempDir.path()).permissions()))));
|
|
QVERIFY(tempSubDir2.cd("sub-dir-2"));
|
|
|
|
tempFile1.reset(new QFile(tempDir.path() + "/file1.txt"));
|
|
QVERIFY(tempFile1->open(QIODevice::ReadWrite));
|
|
|
|
tempFile2.reset(new QFile(tempDir.path() + "/file2.txt"));
|
|
QVERIFY(tempFile2->open(QIODevice::ReadWrite));
|
|
|
|
// Ensure that each test starts off in the temporary directory.
|
|
oldCurrentDir = QDir::current();
|
|
QDir::setCurrent(tempDir.path());
|
|
}
|
|
|
|
void tst_QQuickFolderDialogImpl::cleanupTestCase()
|
|
{
|
|
// Just in case...
|
|
QDir::setCurrent(oldCurrentDir.path());
|
|
}
|
|
|
|
void tst_QQuickFolderDialogImpl::defaults()
|
|
{
|
|
QTest::failOnWarning(QRegularExpression(".*"));
|
|
QQuickApplicationHelper helper(this, "folderDialog.qml");
|
|
QVERIFY2(helper.ready, helper.failureMessage());
|
|
|
|
QQuickWindow *window = helper.window;
|
|
window->show();
|
|
window->requestActivate();
|
|
QVERIFY(QTest::qWaitForWindowExposed(window));
|
|
|
|
QQuickFolderDialog *dialog = window->property("dialog").value<QQuickFolderDialog*>();
|
|
QVERIFY(dialog);
|
|
COMPARE_URL(dialog->currentFolder(), QUrl::fromLocalFile(QDir().absolutePath()));
|
|
// The first file in the directory should be selected, but not until the dialog is actually open,
|
|
// as QQuickFileDialogImpl hasn't been created yet.
|
|
COMPARE_URL(dialog->selectedFolder(), QUrl());
|
|
QCOMPARE(dialog->title(), QString());
|
|
|
|
dialog->open();
|
|
QQuickFolderDialogImpl *quickDialog = window->findChild<QQuickFolderDialogImpl*>();
|
|
QVERIFY(quickDialog);
|
|
QTRY_VERIFY(quickDialog->isOpened());
|
|
QVERIFY(quickDialog);
|
|
COMPARE_URL(quickDialog->selectedFolder(), QUrl::fromLocalFile(tempSubDir1.path()));
|
|
COMPARE_URL(quickDialog->currentFolder(), QUrl::fromLocalFile(QDir().absolutePath()));
|
|
COMPARE_URL(dialog->selectedFolder(), QUrl::fromLocalFile(tempSubDir1.path()));
|
|
COMPARE_URL(dialog->currentFolder(), QUrl::fromLocalFile(QDir().absolutePath()));
|
|
QCOMPARE(quickDialog->title(), QString());
|
|
}
|
|
|
|
typedef DialogTestHelper<QQuickFolderDialog, QQuickFolderDialogImpl> FolderDialogTestHelper;
|
|
|
|
class FolderDialogSignalHelper
|
|
{
|
|
public:
|
|
FolderDialogSignalHelper(const FolderDialogTestHelper &dialogTestHelper) :
|
|
dialogSelectedFolderChangedSpy(dialogTestHelper.dialog, SIGNAL(selectedFolderChanged())),
|
|
quickDialogSelectedFolderChangedSpy(dialogTestHelper.quickDialog, SIGNAL(selectedFolderChanged(QUrl))),
|
|
dialogCurrentFolderChangedSpy(dialogTestHelper.dialog, SIGNAL(currentFolderChanged())),
|
|
quickDialogCurrentFolderChangedSpy(dialogTestHelper.quickDialog, SIGNAL(currentFolderChanged(QUrl)))
|
|
{
|
|
if (!dialogSelectedFolderChangedSpy.isValid())
|
|
errorMessage = "selectedFolderChanged signal of dialog is not valid";
|
|
if (!quickDialogSelectedFolderChangedSpy.isValid())
|
|
errorMessage = "selectedFolderChanged signal of quickDialog is not valid";
|
|
if (!dialogCurrentFolderChangedSpy.isValid())
|
|
errorMessage = "currentFolderChanged signal of dialog is not valid";
|
|
if (!quickDialogCurrentFolderChangedSpy.isValid())
|
|
errorMessage = "currentFolderChanged signal of quickDialog is not valid";
|
|
}
|
|
|
|
QSignalSpy dialogSelectedFolderChangedSpy;
|
|
QSignalSpy quickDialogSelectedFolderChangedSpy;
|
|
QSignalSpy dialogCurrentFolderChangedSpy;
|
|
QSignalSpy quickDialogCurrentFolderChangedSpy;
|
|
|
|
QByteArray errorMessage;
|
|
};
|
|
|
|
void tst_QQuickFolderDialogImpl::chooseFolderViaStandardButtons()
|
|
{
|
|
// Open the dialog.
|
|
FolderDialogTestHelper dialogHelper(this, "folderDialog.qml");
|
|
QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage());
|
|
QVERIFY(dialogHelper.waitForWindowActive());
|
|
QVERIFY(dialogHelper.openDialog());
|
|
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
|
|
|
|
// Select the delegate by clicking once.
|
|
const FolderDialogSignalHelper signalHelper(dialogHelper);
|
|
QVERIFY2(signalHelper.errorMessage.isEmpty(), signalHelper.errorMessage);
|
|
auto folderDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("folderDialogListView");
|
|
QVERIFY(folderDialogListView);
|
|
QQuickFileDialogDelegate *delegate = nullptr;
|
|
QTRY_VERIFY(findViewDelegateItem(folderDialogListView, 1, delegate));
|
|
COMPARE_URL(delegate->file(), QUrl::fromLocalFile(tempSubDir2.path()));
|
|
QVERIFY(clickButton(delegate));
|
|
// currentFolder shouldn't change just from a single click.
|
|
COMPARE_URL(dialogHelper.quickDialog->currentFolder(), QUrl::fromLocalFile(tempDir.path()));
|
|
COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempDir.path()));
|
|
COMPARE_URL(dialogHelper.quickDialog->selectedFolder(), QUrl::fromLocalFile(tempSubDir2.path()));
|
|
COMPARE_URL(dialogHelper.dialog->selectedFolder(), QUrl::fromLocalFile(tempSubDir2.path()));
|
|
// Only selectedFile-related signals should be emitted.
|
|
QCOMPARE(signalHelper.dialogSelectedFolderChangedSpy.size(), 1);
|
|
QCOMPARE(signalHelper.quickDialogSelectedFolderChangedSpy.size(), 1);
|
|
QCOMPARE(signalHelper.dialogCurrentFolderChangedSpy.size(), 0);
|
|
QCOMPARE(signalHelper.quickDialogCurrentFolderChangedSpy.size(), 0);
|
|
|
|
// Click the "Open" button.
|
|
QVERIFY(dialogHelper.quickDialog->footer());
|
|
auto dialogButtonBox = qobject_cast<QQuickDialogButtonBox*>(dialogHelper.quickDialog->footer());
|
|
QVERIFY(dialogButtonBox);
|
|
QQuickAbstractButton* openButton = findDialogButton(dialogButtonBox, "Open");
|
|
QVERIFY(openButton);
|
|
QVERIFY(clickButton(openButton));
|
|
COMPARE_URL(dialogHelper.dialog->selectedFolder(), QUrl::fromLocalFile(tempSubDir2.path()));
|
|
COMPARE_URL(dialogHelper.quickDialog->selectedFolder(), QUrl::fromLocalFile(tempSubDir2.path()));
|
|
QCOMPARE(signalHelper.dialogSelectedFolderChangedSpy.size(), 1);
|
|
QCOMPARE(signalHelper.quickDialogSelectedFolderChangedSpy.size(), 1);
|
|
QCOMPARE(signalHelper.dialogCurrentFolderChangedSpy.size(), 0);
|
|
QCOMPARE(signalHelper.quickDialogCurrentFolderChangedSpy.size(), 0);
|
|
QTRY_VERIFY(!dialogHelper.quickDialog->isVisible());
|
|
QVERIFY(!dialogHelper.dialog->isVisible());
|
|
}
|
|
|
|
void tst_QQuickFolderDialogImpl::bindCurrentFolder_data()
|
|
{
|
|
QTest::addColumn<QUrl>("initialFolder");
|
|
QTest::addColumn<QUrl>("expectedFolder");
|
|
QTest::addColumn<QStringList>("expectedVisibleFiles");
|
|
|
|
const auto currentDirUrl = QUrl::fromLocalFile(QDir::current().path());
|
|
const auto tempSubDirUrl = QUrl::fromLocalFile(tempSubDir1.path());
|
|
const auto tempSubFile1Url = QUrl::fromLocalFile(tempSubFile1->fileName());
|
|
|
|
const QStringList currentDirFiles = { tempSubDir1.path(), tempSubDir2.path() };
|
|
const QStringList tempSubDirFiles = { tempSubSubDir.path() };
|
|
|
|
// Setting the folder to "sub-dir-1" should result in "sub-sub-dir" being visible.
|
|
QTest::addRow("sub-dir-1") << tempSubDirUrl << tempSubDirUrl << tempSubDirFiles;
|
|
// Setting a file as the folder shouldn't work, and the dialog shouldn't change its folder.
|
|
QTest::addRow("sub-dir/sub-file1.txt") << tempSubFile1Url << currentDirUrl << currentDirFiles;
|
|
}
|
|
|
|
void tst_QQuickFolderDialogImpl::bindCurrentFolder()
|
|
{
|
|
QFETCH(QUrl, initialFolder);
|
|
QFETCH(QUrl, expectedFolder);
|
|
QFETCH(QStringList, expectedVisibleFiles);
|
|
|
|
// Open the dialog.
|
|
FolderDialogTestHelper dialogHelper(this, "bindCurrentFolder.qml", {},
|
|
{{ "initialFolder", initialFolder }});
|
|
QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage());
|
|
QVERIFY(dialogHelper.waitForWindowActive());
|
|
QVERIFY(dialogHelper.openDialog());
|
|
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
|
|
COMPARE_URL(dialogHelper.dialog->currentFolder(), expectedFolder);
|
|
|
|
auto folderDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("folderDialogListView");
|
|
QVERIFY(folderDialogListView);
|
|
QString failureMessage;
|
|
// Even waiting for ListView polish and that the FolderListModel's status is ready aren't enough
|
|
// on Windows, apparently, as sometimes there just aren't any delegates by the time we do the check.
|
|
// So, we use QTRY_VERIFY2 each time we call this function just to be safe.
|
|
QTRY_VERIFY2(verifyFileDialogDelegates(folderDialogListView, expectedVisibleFiles, failureMessage), qPrintable(failureMessage));
|
|
|
|
// Check that the breadcrumb bar is correct by constructing the expected files from the expectedFolder.
|
|
auto breadcrumbBar = dialogHelper.quickDialog->findChild<QQuickFolderBreadcrumbBar*>();
|
|
QVERIFY(breadcrumbBar);
|
|
QVERIFY2(verifyBreadcrumbDelegates(breadcrumbBar, expectedFolder, failureMessage), qPrintable(failureMessage));
|
|
}
|
|
|
|
void tst_QQuickFolderDialogImpl::changeFolderViaDoubleClick()
|
|
{
|
|
// Open the dialog.
|
|
FolderDialogTestHelper dialogHelper(this, "folderDialog.qml");
|
|
QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage());
|
|
QVERIFY(dialogHelper.waitForWindowActive());
|
|
QVERIFY(dialogHelper.openDialog());
|
|
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
|
|
|
|
// Double-click on the "sub-dir-2" delegate.
|
|
const FolderDialogSignalHelper signalHelper(dialogHelper);
|
|
QVERIFY2(signalHelper.errorMessage.isEmpty(), signalHelper.errorMessage);
|
|
auto folderDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("folderDialogListView");
|
|
QVERIFY(folderDialogListView);
|
|
QQuickFileDialogDelegate *delegate = nullptr;
|
|
QTRY_VERIFY(findViewDelegateItem(folderDialogListView, 1, delegate));
|
|
COMPARE_URL(delegate->file(), QUrl::fromLocalFile(tempSubDir2.path()))
|
|
QVERIFY(doubleClickButton(delegate));
|
|
COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempSubDir2.path()))
|
|
COMPARE_URL(dialogHelper.dialog->selectedFolder(), QUrl());
|
|
// selectedFolder is set to the folder when clicked and then set to an empty URL after
|
|
// the double click.
|
|
QCOMPARE(signalHelper.dialogSelectedFolderChangedSpy.size(), 2);
|
|
QCOMPARE(signalHelper.quickDialogSelectedFolderChangedSpy.size(), 2);
|
|
QCOMPARE(signalHelper.dialogCurrentFolderChangedSpy.size(), 1);
|
|
QCOMPARE(signalHelper.quickDialogCurrentFolderChangedSpy.size(), 1);
|
|
// Since we only changed the current folder, the dialog should still be open.
|
|
QVERIFY(dialogHelper.dialog->isVisible());
|
|
|
|
dialogHelper.dialog->close();
|
|
QVERIFY(!dialogHelper.dialog->isVisible());
|
|
QTRY_VERIFY(!dialogHelper.quickDialog->isVisible());
|
|
}
|
|
|
|
void tst_QQuickFolderDialogImpl::changeFolderViaTextEdit()
|
|
{
|
|
// Open the dialog.
|
|
FolderDialogTestHelper dialogHelper(this, "folderDialog.qml");
|
|
QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage());
|
|
QVERIFY(dialogHelper.waitForWindowActive());
|
|
QVERIFY(dialogHelper.openDialog());
|
|
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
|
|
QVERIFY(dialogHelper.waitForPopupWindowActiveAndPolished());
|
|
|
|
#if QT_CONFIG(shortcut)
|
|
// Get the text edit visible with Ctrl+L.
|
|
const auto editPathKeySequence = QKeySequence(Qt::CTRL | Qt::Key_L);
|
|
QTest::keySequence(dialogHelper.popupWindow(), editPathKeySequence);
|
|
auto breadcrumbBar = dialogHelper.quickDialog->findChild<QQuickFolderBreadcrumbBar*>();
|
|
QVERIFY(breadcrumbBar);
|
|
QVERIFY(breadcrumbBar->textField()->isVisible());
|
|
QCOMPARE(breadcrumbBar->textField()->text(), dialogHelper.dialog->currentFolder().toLocalFile());
|
|
QCOMPARE(breadcrumbBar->textField()->selectedText(), breadcrumbBar->textField()->text());
|
|
|
|
// Enter the path to the folder in the text edit.
|
|
enterText(dialogHelper.popupWindow(), tempSubDir2.path());
|
|
QCOMPARE(breadcrumbBar->textField()->text(), tempSubDir2.path());
|
|
#endif
|
|
|
|
// Hit enter to accept.
|
|
QTest::keyClick(dialogHelper.popupWindow(), Qt::Key_Return);
|
|
COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempSubDir2.path()));
|
|
COMPARE_URL(dialogHelper.quickDialog->currentFolder(), QUrl::fromLocalFile(tempSubDir2.path()));
|
|
// We changed into a directory with no folders, so the selected folder should be invalid.
|
|
COMPARE_URL(dialogHelper.dialog->selectedFolder(), QUrl());
|
|
COMPARE_URL(dialogHelper.quickDialog->selectedFolder(), QUrl());
|
|
QTRY_VERIFY(dialogHelper.dialog->isVisible());
|
|
|
|
// Close the dialog.
|
|
dialogHelper.dialog->close();
|
|
QVERIFY(!dialogHelper.dialog->isVisible());
|
|
QTRY_VERIFY(!dialogHelper.quickDialog->isVisible());
|
|
}
|
|
|
|
void tst_QQuickFolderDialogImpl::changeFolderViaEnter()
|
|
{
|
|
// Open the dialog.
|
|
FolderDialogTestHelper dialogHelper(this, "folderDialog.qml");
|
|
QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage());
|
|
QVERIFY(dialogHelper.waitForWindowActive());
|
|
QVERIFY(dialogHelper.openDialog());
|
|
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
|
|
QVERIFY(dialogHelper.waitForPopupWindowActiveAndPolished());
|
|
|
|
// The first delegate in the view should be selected and have focus.
|
|
COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempDir.path()));
|
|
auto folderDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("folderDialogListView");
|
|
QVERIFY(folderDialogListView);
|
|
QQuickFileDialogDelegate *subDir1Delegate = nullptr;
|
|
QTRY_VERIFY(findViewDelegateItem(folderDialogListView, 0, subDir1Delegate));
|
|
COMPARE_URL(subDir1Delegate->file(), QUrl::fromLocalFile(tempSubDir1.path()));
|
|
QVERIFY(subDir1Delegate->hasActiveFocus());
|
|
|
|
// Select the delegate by pressing enter.
|
|
const FolderDialogSignalHelper signalHelper(dialogHelper);
|
|
QVERIFY2(signalHelper.errorMessage.isEmpty(), signalHelper.errorMessage);
|
|
QTest::keyClick(dialogHelper.popupWindow(), Qt::Key_Return);
|
|
COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempSubDir1.path()));
|
|
COMPARE_URL(dialogHelper.dialog->selectedFolder(), QUrl::fromLocalFile(tempSubSubDir.path()));
|
|
QCOMPARE(signalHelper.dialogSelectedFolderChangedSpy.size(), 1);
|
|
QCOMPARE(signalHelper.quickDialogSelectedFolderChangedSpy.size(), 1);
|
|
QCOMPARE(signalHelper.dialogCurrentFolderChangedSpy.size(), 1);
|
|
QCOMPARE(signalHelper.quickDialogCurrentFolderChangedSpy.size(), 1);
|
|
// Since we only changed the current folder, the dialog should still be open.
|
|
QVERIFY(dialogHelper.dialog->isVisible());
|
|
|
|
dialogHelper.dialog->close();
|
|
QVERIFY(!dialogHelper.dialog->isVisible());
|
|
QTRY_VERIFY(!dialogHelper.quickDialog->isVisible());
|
|
}
|
|
|
|
void tst_QQuickFolderDialogImpl::cancelDialogWhileTextEditHasFocus()
|
|
{
|
|
// Open the dialog.
|
|
FolderDialogTestHelper dialogHelper(this, "folderDialog.qml");
|
|
QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage());
|
|
QVERIFY(dialogHelper.waitForWindowActive());
|
|
QVERIFY(dialogHelper.openDialog());
|
|
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
|
|
QVERIFY(dialogHelper.waitForPopupWindowActiveAndPolished());
|
|
|
|
#if QT_CONFIG(shortcut)
|
|
// Get the text edit visible with Ctrl+L.
|
|
const auto editPathKeySequence = QKeySequence(Qt::CTRL | Qt::Key_L);
|
|
QTest::keySequence(dialogHelper.popupWindow(), editPathKeySequence);
|
|
#endif
|
|
auto breadcrumbBar = dialogHelper.quickDialog->findChild<QQuickFolderBreadcrumbBar*>();
|
|
QVERIFY(breadcrumbBar);
|
|
QVERIFY(breadcrumbBar->textField()->isVisible());
|
|
QCOMPARE(breadcrumbBar->textField()->text(), dialogHelper.dialog->currentFolder().toLocalFile());
|
|
QCOMPARE(breadcrumbBar->textField()->selectedText(), breadcrumbBar->textField()->text());
|
|
|
|
// Close it via the cancel button.
|
|
auto dialogButtonBox = qobject_cast<QQuickDialogButtonBox*>(dialogHelper.quickDialog->footer());
|
|
QVERIFY(dialogButtonBox);
|
|
const QString cancelText = QQuickDialogButtonBoxPrivate::buttonText(QPlatformDialogHelper::Cancel);
|
|
auto cancelButton = findDialogButton(dialogButtonBox, cancelText);
|
|
QVERIFY(cancelButton);
|
|
QVERIFY(clickButton(cancelButton));
|
|
|
|
// Open it again. The text field should not be visible, but the breadcrumb bar itself should be.
|
|
dialogHelper.dialog->open();
|
|
QVERIFY(dialogHelper.dialog->isVisible());
|
|
QTRY_VERIFY(dialogHelper.quickDialog->isOpened());
|
|
QVERIFY(breadcrumbBar->isVisible());
|
|
// The ListView that contains the breadcrumb delegates should be visible.
|
|
QVERIFY(breadcrumbBar->contentItem()->isVisible());
|
|
QVERIFY(!breadcrumbBar->textField()->isVisible());
|
|
}
|
|
|
|
void tst_QQuickFolderDialogImpl::goUp()
|
|
{
|
|
// Open the dialog, starting off in "sub-dir-1".
|
|
FolderDialogTestHelper dialogHelper(this, "bindCurrentFolder.qml", {},
|
|
{{ "initialFolder", QUrl::fromLocalFile(tempSubDir1.path()) }});
|
|
QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage());
|
|
QVERIFY(dialogHelper.waitForWindowActive());
|
|
QVERIFY(dialogHelper.openDialog());
|
|
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
|
|
|
|
// Go up a directory via the button next to the breadcrumb bar.
|
|
auto breadcrumbBar = dialogHelper.quickDialog->findChild<QQuickFolderBreadcrumbBar*>();
|
|
QVERIFY(breadcrumbBar);
|
|
auto barListView = qobject_cast<QQuickListView*>(breadcrumbBar->contentItem());
|
|
QVERIFY(barListView);
|
|
if (QQuickTest::qIsPolishScheduled(barListView))
|
|
QVERIFY(QQuickTest::qWaitForPolish(barListView));
|
|
QVERIFY(clickButton(breadcrumbBar->upButton()));
|
|
COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempDir.path()));
|
|
// The previous directory that we were in should now be selected (matches e.g. Windows and Ubuntu).
|
|
COMPARE_URL(dialogHelper.dialog->selectedFolder(), QUrl::fromLocalFile(tempSubDir1.path()));
|
|
auto folderDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("folderDialogListView");
|
|
QVERIFY(folderDialogListView);
|
|
QQuickFileDialogDelegate *subDirDelegate = nullptr;
|
|
QTRY_VERIFY(findViewDelegateItem(folderDialogListView, 0, subDirDelegate));
|
|
QCOMPARE(subDirDelegate->isHighlighted(), true);
|
|
|
|
#if QT_CONFIG(shortcut)
|
|
// Go up a directory via the keyboard shortcut.
|
|
const auto goUpKeySequence = QKeySequence(Qt::ALT | Qt::Key_Up);
|
|
QTest::keySequence(dialogHelper.window(), goUpKeySequence);
|
|
QDir tempParentDir(tempDir.path());
|
|
QVERIFY(tempParentDir.cdUp());
|
|
COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempParentDir.path()));
|
|
COMPARE_URL(dialogHelper.dialog->selectedFolder(), QUrl::fromLocalFile(tempDir.path()));
|
|
#endif
|
|
}
|
|
|
|
void tst_QQuickFolderDialogImpl::goUpWhileTextEditHasFocus()
|
|
{
|
|
// Open the dialog, starting off in "sub-dir-1".
|
|
FolderDialogTestHelper dialogHelper(this, "bindCurrentFolder.qml", {},
|
|
{{ "initialFolder", QUrl::fromLocalFile(tempSubDir1.path()) }});
|
|
QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage());
|
|
QVERIFY(dialogHelper.waitForWindowActive());
|
|
QVERIFY(dialogHelper.openDialog());
|
|
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
|
|
QVERIFY(dialogHelper.waitForPopupWindowActiveAndPolished());
|
|
|
|
// Go up a directory via the button next to the breadcrumb bar.
|
|
auto breadcrumbBar = dialogHelper.quickDialog->findChild<QQuickFolderBreadcrumbBar*>();
|
|
QVERIFY(breadcrumbBar);
|
|
auto barListView = qobject_cast<QQuickListView*>(breadcrumbBar->contentItem());
|
|
QVERIFY(barListView);
|
|
if (QQuickTest::qIsPolishScheduled(barListView))
|
|
QVERIFY(QQuickTest::qWaitForPolish(barListView));
|
|
QVERIFY(clickButton(breadcrumbBar->upButton()));
|
|
// The path should have changed to the parent directory.
|
|
COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempDir.path()));
|
|
// The text edit should be hidden when it loses focus.
|
|
QVERIFY(!breadcrumbBar->textField()->hasActiveFocus());
|
|
QVERIFY(!breadcrumbBar->textField()->isVisible());
|
|
// The focus should be given to the first delegate.
|
|
QVERIFY(dialogHelper.popupWindow()->activeFocusItem());
|
|
auto folderDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("folderDialogListView");
|
|
QVERIFY(folderDialogListView);
|
|
QQuickFileDialogDelegate *firstDelegate = nullptr;
|
|
QTRY_VERIFY(findViewDelegateItem(folderDialogListView, 0, firstDelegate));
|
|
QCOMPARE(dialogHelper.popupWindow()->activeFocusItem(), firstDelegate);
|
|
}
|
|
|
|
void tst_QQuickFolderDialogImpl::goIntoLargeFolder()
|
|
{
|
|
// Create a throwaway directory with a lot of folders within it...
|
|
QTemporaryDir anotherTempDir;
|
|
QVERIFY(anotherTempDir.isValid());
|
|
for (int i = 0; i < 30; ++i) {
|
|
QDir newDir(anotherTempDir.path());
|
|
QVERIFY(newDir.exists());
|
|
// Pad with zeroes so that the directories are ordered as we expect.
|
|
QVERIFY(newDir.mkdir(QString::fromLatin1("dir%1").arg(i, 2, 10, QLatin1Char('0'))));
|
|
}
|
|
|
|
// ... and within one of those folders, more folders.
|
|
QDir dir20(anotherTempDir.path() + "/dir20");
|
|
QVERIFY(dir20.exists());
|
|
for (int i = 0; i < 30; ++i) {
|
|
QDir newDir(dir20.path());
|
|
QVERIFY(newDir.exists());
|
|
QVERIFY(newDir.mkdir(QString::fromLatin1("subdir%1").arg(i, 2, 10, QLatin1Char('0'))));
|
|
}
|
|
|
|
// Open the dialog. Start off in the throwaway directory.
|
|
FolderDialogTestHelper dialogHelper(this, "bindCurrentFolder.qml", {},
|
|
{{ "initialFolder", QUrl::fromLocalFile(anotherTempDir.path()) }});
|
|
QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage());
|
|
QVERIFY(dialogHelper.waitForWindowActive());
|
|
QVERIFY(dialogHelper.openDialog());
|
|
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
|
|
|
|
// If the screen is so tall that the contentItem is not vertically larger than the view,
|
|
// then the test makes no sense.
|
|
auto folderDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("folderDialogListView");
|
|
QVERIFY(folderDialogListView);
|
|
if (QQuickTest::qIsPolishScheduled(folderDialogListView))
|
|
QVERIFY(QQuickTest::qWaitForPolish(folderDialogListView));
|
|
// Just to be safe, make sure it's at least twice as big.
|
|
if (folderDialogListView->contentItem()->height() < folderDialogListView->height() * 2) {
|
|
QSKIP(qPrintable(QString::fromLatin1("Expected height of folderDialogListView's contentItem (%1)" \
|
|
" to be at least twice as big as the ListView's height (%2)")
|
|
.arg(folderDialogListView->contentItem()->height()).arg(folderDialogListView->height())));
|
|
}
|
|
|
|
// Scroll down to dir20. The view should be somewhere past the middle.
|
|
QVERIFY(QMetaObject::invokeMethod(folderDialogListView, "positionViewAtIndex", Qt::DirectConnection,
|
|
Q_ARG(int, 20), Q_ARG(int, QQuickItemView::PositionMode::Center)));
|
|
QVERIFY(folderDialogListView->contentY() > 0);
|
|
|
|
// Go into it. The view should start at the top of the directory, not at the same contentY
|
|
// that it had in the previous directory.
|
|
QQuickFileDialogDelegate *dir20Delegate = nullptr;
|
|
QTRY_VERIFY(findViewDelegateItem(folderDialogListView, 20, dir20Delegate));
|
|
COMPARE_URL(dir20Delegate->file(), QUrl::fromLocalFile(dir20.path()));
|
|
QVERIFY(doubleClickButton(dir20Delegate));
|
|
COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(dir20.path()));
|
|
COMPARE_URL(dialogHelper.quickDialog->currentFolder(), QUrl::fromLocalFile(dir20.path()));
|
|
QCOMPARE(folderDialogListView->contentY(), 0);
|
|
}
|
|
|
|
void tst_QQuickFolderDialogImpl::clickOnBreadcrumb()
|
|
{
|
|
// Open the dialog, starting off in "sub-dir-1".
|
|
FolderDialogTestHelper dialogHelper(this, "bindCurrentFolder.qml", {},
|
|
{{ "initialFolder", QUrl::fromLocalFile(tempSubDir1.path()) }});
|
|
QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage());
|
|
QVERIFY(dialogHelper.waitForWindowActive());
|
|
QVERIFY(dialogHelper.openDialog());
|
|
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
|
|
|
|
// Find the breadcrumb bar delegate for the temp directory (parent of "sub-dir-1").
|
|
auto breadcrumbBar = dialogHelper.quickDialog->findChild<QQuickFolderBreadcrumbBar*>();
|
|
QVERIFY(breadcrumbBar);
|
|
auto breadcrumbBarListView = qobject_cast<QQuickListView*>(breadcrumbBar->contentItem());
|
|
QVERIFY(breadcrumbBarListView);
|
|
QQuickAbstractButton *breadcrumbDelegate = nullptr;
|
|
// The following breadcrumb bar has 5 delegates:
|
|
// [ / > tmp > deadbeef ]
|
|
// We can assume that, regardless of which system we're running on, we'll have
|
|
// at least 3: one for the temp directory, and one for the > separator, and one for "sub-dir-1".
|
|
QVERIFY(breadcrumbBarListView->count() >= 3);
|
|
// - 1 to make it zero-based, and another 2 to get to the second-last directory, which is the parent of "sub-dir-1".
|
|
QTRY_VERIFY(findViewDelegateItem(breadcrumbBarListView, breadcrumbBarListView->count() - 3, breadcrumbDelegate));
|
|
|
|
QVERIFY(clickButton(breadcrumbDelegate));
|
|
QCOMPARE(dialogHelper.quickDialog->currentFolder(), QUrl::fromLocalFile(tempDir.path()));
|
|
QCOMPARE(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempDir.path()));
|
|
QCOMPARE(dialogHelper.quickDialog->selectedFolder(), QUrl::fromLocalFile(tempSubDir1.path()));
|
|
QCOMPARE(dialogHelper.dialog->selectedFolder(), QUrl::fromLocalFile(tempSubDir1.path()));
|
|
}
|
|
|
|
void tst_QQuickFolderDialogImpl::keyAndShortcutHandling()
|
|
{
|
|
// Open the dialog.
|
|
FolderDialogTestHelper dialogHelper(this, "folderDialog.qml");
|
|
QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage());
|
|
QVERIFY(dialogHelper.waitForWindowActive());
|
|
QVERIFY(dialogHelper.openDialog());
|
|
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
|
|
QVERIFY(dialogHelper.waitForPopupWindowActiveAndPolished());
|
|
|
|
#if QT_CONFIG(shortcut)
|
|
// Get the text edit visible with Ctrl+L.
|
|
const auto editPathKeySequence = QKeySequence(Qt::CTRL | Qt::Key_L);
|
|
QTest::keySequence(dialogHelper.popupWindow(), editPathKeySequence);
|
|
#endif
|
|
auto breadcrumbBar = dialogHelper.quickDialog->findChild<QQuickFolderBreadcrumbBar*>();
|
|
QVERIFY(breadcrumbBar);
|
|
QVERIFY(breadcrumbBar->textField()->isVisible());
|
|
QCOMPARE(breadcrumbBar->textField()->text(), dialogHelper.dialog->currentFolder().toLocalFile());
|
|
QCOMPARE(breadcrumbBar->textField()->selectedText(), breadcrumbBar->textField()->text());
|
|
|
|
#if QT_CONFIG(shortcut)
|
|
// Ctrl+L shouldn't hide it.
|
|
QTest::keySequence(dialogHelper.popupWindow(), editPathKeySequence);
|
|
QVERIFY(breadcrumbBar->textField()->isVisible());
|
|
#endif
|
|
|
|
// Cancel it with the escape key.
|
|
QTest::keyClick(dialogHelper.popupWindow(), Qt::Key_Escape);
|
|
QVERIFY(!breadcrumbBar->textField()->isVisible());
|
|
QVERIFY(dialogHelper.dialog->isVisible());
|
|
|
|
#if QT_CONFIG(shortcut)
|
|
// Make it visible.
|
|
QTest::keySequence(dialogHelper.popupWindow(), editPathKeySequence);
|
|
QVERIFY(breadcrumbBar->textField()->isVisible());
|
|
#endif
|
|
|
|
// Cancel it with the escape key again.
|
|
QTest::keyClick(dialogHelper.popupWindow(), Qt::Key_Escape);
|
|
QVERIFY(!breadcrumbBar->textField()->isVisible());
|
|
QVERIFY(dialogHelper.dialog->isVisible());
|
|
|
|
// Pressing escape now should close the dialog.
|
|
QTest::keyClick(dialogHelper.popupWindow(), Qt::Key_Escape);
|
|
QVERIFY(!dialogHelper.dialog->isVisible());
|
|
QTRY_VERIFY(!dialogHelper.quickDialog->isVisible());
|
|
}
|
|
|
|
void tst_QQuickFolderDialogImpl::tabFocusNavigation()
|
|
{
|
|
// Open the dialog.
|
|
FolderDialogTestHelper dialogHelper(this, "folderDialog.qml");
|
|
QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage());
|
|
QVERIFY(dialogHelper.waitForWindowActive());
|
|
QVERIFY(dialogHelper.openDialog());
|
|
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
|
|
QVERIFY(dialogHelper.waitForPopupWindowActiveAndPolished());
|
|
|
|
QList<QQuickItem*> expectedFocusItems;
|
|
|
|
// The initial focus should be on the first delegate.
|
|
auto folderDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("folderDialogListView");
|
|
QVERIFY(folderDialogListView);
|
|
QQuickFileDialogDelegate *firstDelegate = nullptr;
|
|
QTRY_VERIFY(findViewDelegateItem(folderDialogListView, 0, firstDelegate));
|
|
expectedFocusItems << firstDelegate;
|
|
|
|
// Next, the left-most dialog button.
|
|
auto dialogButtonBox = qobject_cast<QQuickDialogButtonBox*>(dialogHelper.quickDialog->footer());
|
|
QVERIFY(dialogButtonBox);
|
|
QCOMPARE(dialogButtonBox->count(), 2);
|
|
auto leftMostButton = qobject_cast<QQuickAbstractButton*>(dialogButtonBox->itemAt(0));
|
|
QVERIFY(leftMostButton);
|
|
expectedFocusItems << leftMostButton;
|
|
|
|
// Then, the right-most dialog button.
|
|
auto rightMostButton = qobject_cast<QQuickAbstractButton*>(dialogButtonBox->itemAt(1));
|
|
QVERIFY(rightMostButton);
|
|
expectedFocusItems << rightMostButton;
|
|
|
|
// Then, the up button.
|
|
auto breadcrumbBar = dialogHelper.quickDialog->findChild<QQuickFolderBreadcrumbBar*>();
|
|
QVERIFY(breadcrumbBar);
|
|
expectedFocusItems << breadcrumbBar->upButton();
|
|
|
|
// Finally, add each bread crumb delegate.
|
|
for (int i = 0; i < folderDialogListView->count(); ++i) {
|
|
QQuickFileDialogDelegate *delegate = nullptr;
|
|
QTRY_VERIFY(findViewDelegateItem(folderDialogListView, i, delegate));
|
|
expectedFocusItems << delegate;
|
|
}
|
|
|
|
// Tab through each item, checking the focus after each.
|
|
for (auto expectedFocusItem : std::as_const(expectedFocusItems)) {
|
|
// Check the focus item first so that we account for the first item.
|
|
// Print detailed failure message as workaround for QTBUG-92102.
|
|
QVERIFY2(dialogHelper.popupWindow()->activeFocusItem() == expectedFocusItem, qPrintable(QString::fromLatin1(
|
|
"\n Actual: %1\n Expected: %2").arg(QDebug::toString(dialogHelper.popupWindow()->activeFocusItem()))
|
|
.arg(QDebug::toString(expectedFocusItem))));
|
|
|
|
if (expectedFocusItem != expectedFocusItems.last())
|
|
QTest::keyClick(dialogHelper.popupWindow(), Qt::Key_Tab);
|
|
}
|
|
|
|
// Ensure the order is reversed when shift-tabbing.
|
|
std::reverse(expectedFocusItems.begin(), expectedFocusItems.end());
|
|
// We know the first (last) item has focus already, so skip it.
|
|
expectedFocusItems.removeFirst();
|
|
for (auto expectedFocusItem : std::as_const(expectedFocusItems)) {
|
|
QTest::keyClick(dialogHelper.popupWindow(), Qt::Key_Tab, Qt::ShiftModifier);
|
|
|
|
QCOMPARE(dialogHelper.popupWindow()->activeFocusItem(), expectedFocusItem);
|
|
}
|
|
}
|
|
|
|
void tst_QQuickFolderDialogImpl::acceptRejectLabel()
|
|
{
|
|
// Open the dialog.
|
|
FolderDialogTestHelper dialogHelper(this, "acceptRejectLabel.qml");
|
|
QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage());
|
|
QVERIFY(dialogHelper.waitForWindowActive());
|
|
QVERIFY(dialogHelper.openDialog());
|
|
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
|
|
|
|
// Check that the accept and reject buttons' labels have changed.
|
|
auto dialogButtonBox = qobject_cast<QQuickDialogButtonBox*>(dialogHelper.quickDialog->footer());
|
|
QVERIFY(dialogButtonBox);
|
|
QVERIFY(findDialogButton(dialogButtonBox, "AcceptTest"));
|
|
QVERIFY(findDialogButton(dialogButtonBox, "RejectTest"));
|
|
|
|
// Close the dialog.
|
|
dialogHelper.dialog->close();
|
|
QVERIFY(!dialogHelper.dialog->isVisible());
|
|
QTRY_VERIFY(!dialogHelper.quickDialog->isVisible());
|
|
|
|
// Reset back to the default text.
|
|
dialogHelper.dialog->resetAcceptLabel();
|
|
dialogHelper.dialog->resetRejectLabel();
|
|
|
|
// Re-open the dialog.
|
|
dialogHelper.dialog->open();
|
|
QVERIFY(dialogHelper.dialog->isVisible());
|
|
QTRY_VERIFY(dialogHelper.quickDialog->isOpened());
|
|
|
|
// Check that the defaults are back.
|
|
const QString openText = QQuickDialogButtonBoxPrivate::buttonText(QPlatformDialogHelper::Open);
|
|
QVERIFY2(findDialogButton(dialogButtonBox, openText), qPrintable(QString::fromLatin1(
|
|
"Failed to find dialog button with text \"%1\"").arg(openText)));
|
|
const QString cancelText = QQuickDialogButtonBoxPrivate::buttonText(QPlatformDialogHelper::Cancel);
|
|
QVERIFY2(findDialogButton(dialogButtonBox, cancelText), qPrintable(QString::fromLatin1(
|
|
"Failed to find dialog button with text \"%1\"").arg(cancelText)));
|
|
}
|
|
|
|
void tst_QQuickFolderDialogImpl::bindTitle()
|
|
{
|
|
// Open the dialog.
|
|
FolderDialogTestHelper dialogHelper(this, "bindTitle.qml");
|
|
QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage());
|
|
QVERIFY(dialogHelper.waitForWindowActive());
|
|
QVERIFY(dialogHelper.openDialog());
|
|
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
|
|
|
|
// Open the dialog and check that the correct title is displayed.
|
|
const QString expectedTitle = QLatin1String("Test Title");
|
|
QCOMPARE(dialogHelper.dialog->title(), expectedTitle);
|
|
QCOMPARE(dialogHelper.quickDialog->title(), expectedTitle);
|
|
auto header = dialogHelper.quickDialog->header();
|
|
QVERIFY(header);
|
|
auto dialogTitleBarLabel = dialogHelper.quickDialog->header()->findChild<QQuickLabel*>("dialogTitleBarLabel");
|
|
QVERIFY(dialogTitleBarLabel);
|
|
QCOMPARE(dialogTitleBarLabel->text(), expectedTitle);
|
|
}
|
|
|
|
void tst_QQuickFolderDialogImpl::itemsDisabledWhenNecessary()
|
|
{
|
|
// Open the dialog.
|
|
FolderDialogTestHelper dialogHelper(this, "bindCurrentFolder.qml", {},
|
|
{{ "initialFolder", QUrl::fromLocalFile(tempSubDir2.path()) }});
|
|
QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage());
|
|
QVERIFY(dialogHelper.waitForWindowActive());
|
|
QVERIFY(dialogHelper.openDialog());
|
|
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
|
|
COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempSubDir2.path()));
|
|
COMPARE_URL(dialogHelper.quickDialog->currentFolder(), QUrl::fromLocalFile(tempSubDir2.path()));
|
|
QVERIFY(dialogHelper.waitForPopupWindowActiveAndPolished());
|
|
|
|
// We opened it in a folder that has no files, so the Open button should be disabled.
|
|
QVERIFY(dialogHelper.quickDialog->footer());
|
|
auto dialogButtonBox = qobject_cast<QQuickDialogButtonBox*>(dialogHelper.quickDialog->footer());
|
|
QVERIFY(dialogButtonBox);
|
|
QQuickAbstractButton* openButton = findDialogButton(dialogButtonBox, "Open");
|
|
QVERIFY(openButton);
|
|
QCOMPARE(openButton->isEnabled(), false);
|
|
|
|
// Now go up. The Open button should now be enabled.
|
|
auto breadcrumbBar = dialogHelper.quickDialog->findChild<QQuickFolderBreadcrumbBar*>();
|
|
QVERIFY(breadcrumbBar);
|
|
QVERIFY(clickButton(breadcrumbBar->upButton()));
|
|
QCOMPARE(openButton->isEnabled(), true);
|
|
COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempDir.path()));
|
|
COMPARE_URL(dialogHelper.quickDialog->currentFolder(), QUrl::fromLocalFile(tempDir.path()));
|
|
|
|
#if QT_CONFIG(shortcut)
|
|
// Get the text edit visible with Ctrl+L. The Open button should now be disabled.
|
|
const auto editPathKeySequence = QKeySequence(Qt::CTRL | Qt::Key_L);
|
|
QTest::keySequence(dialogHelper.popupWindow(), editPathKeySequence);
|
|
QVERIFY(breadcrumbBar->textField()->isVisible());
|
|
QCOMPARE(openButton->isEnabled(), false);
|
|
#endif
|
|
// Hide it with the escape key. The Open button should now be enabled.
|
|
QTest::keyClick(dialogHelper.popupWindow(), Qt::Key_Escape);
|
|
QVERIFY(!breadcrumbBar->textField()->isVisible());
|
|
QCOMPARE(openButton->isEnabled(), true);
|
|
}
|
|
|
|
void tst_QQuickFolderDialogImpl::done_data()
|
|
{
|
|
QTest::addColumn<QQuickAbstractDialog::StandardCode>("result");
|
|
|
|
QTest::newRow("Accepted") << QQuickAbstractDialog::Accepted;
|
|
QTest::newRow("Rejected") << QQuickAbstractDialog::Rejected;
|
|
}
|
|
|
|
void tst_QQuickFolderDialogImpl::done()
|
|
{
|
|
QFETCH(QQuickAbstractDialog::StandardCode, result);
|
|
|
|
// Open the dialog.
|
|
FolderDialogTestHelper dialogHelper(this, "folderDialog.qml");
|
|
QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage());
|
|
QVERIFY(dialogHelper.waitForWindowActive());
|
|
QVERIFY(dialogHelper.openDialog());
|
|
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
|
|
|
|
// Call the "done" slot manually.
|
|
switch (result) {
|
|
case QQuickAbstractDialog::Accepted:
|
|
QVERIFY(QMetaObject::invokeMethod(dialogHelper.window(), "doneAccepted"));
|
|
break;
|
|
case QQuickAbstractDialog::Rejected:
|
|
QVERIFY(QMetaObject::invokeMethod(dialogHelper.window(), "doneRejected"));
|
|
break;
|
|
}
|
|
|
|
QVERIFY(!dialogHelper.dialog->isVisible());
|
|
QTRY_VERIFY(!dialogHelper.quickDialog->isVisible());
|
|
QCOMPARE(dialogHelper.dialog->result(), result);
|
|
}
|
|
|
|
QTEST_MAIN(tst_QQuickFolderDialogImpl)
|
|
|
|
#include "tst_qquickfolderdialogimpl.moc"
|