Revision control
Copy as Markdown
// 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 <QtQuick/private/qquickmousearea_p.h>
#include <QtQuickTemplates2/private/qquickitemdelegate_p.h>
#include <QtQuickDialogs2/private/qquickfontdialog_p.h>
#include <QtQuickDialogs2QuickImpl/private/qquickfontdialogimpl_p.h>
#include <QtQuickTest/quicktest.h>
#include <QtQuickControlsTestUtils/private/controlstestutils_p.h>
#include <QtQuickControlsTestUtils/private/dialogstestutils_p.h>
#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h>
#include <QtQuickTemplates2/private/qquickcombobox_p.h>
#include <QtQuickTemplates2/private/qquicktextfield_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_QQuickFontDialogImpl : public QQmlDataTest
{
Q_OBJECT
public:
tst_QQuickFontDialogImpl();
private slots:
void initTestCase() override;
void defaults();
void changingWritingSystem();
void clickAroundInTheFamilyListView();
void settingUnderlineAndStrikeoutEffects();
void changeFontSize();
void changeDialogTitle();
void searchFamily();
void setCurrentFontFromApi();
void checkModality_data();
void checkModality();
void checkFrameless();
private:
QQuickAbstractButton *findDialogButton(QQuickDialogButtonBox *box, const QString &buttonText)
{
for (int i = 0; i < box->count(); ++i) {
auto button = qobject_cast<QQuickAbstractButton *>(box->itemAt(i));
if (button && button->text().toUpper() == buttonText.toUpper())
return button;
}
return nullptr;
}
bool closePopup(DialogTestHelper<QQuickFontDialog, QQuickFontDialogImpl> *dialogHelper,
QString dialogButton, QString &failureMessage)
{
auto dialogButtonBox =
dialogHelper->quickDialog->footer()->findChild<QQuickDialogButtonBox *>();
if (!dialogButtonBox) {
failureMessage = QLatin1String("dialogButtonBox is null");
return false;
}
QQuickAbstractButton *openButton = findDialogButton(dialogButtonBox, dialogButton);
if (!openButton) {
failureMessage =
QLatin1String("Couldn't find a button with text '%1'").arg(dialogButton);
return false;
}
bool clicked = clickButton(openButton);
if (!clicked) {
failureMessage = QLatin1String("'%1' button was never clicked").arg(dialogButton);
return false;
}
bool visible = dialogHelper->dialog->isVisible();
if (visible) {
failureMessage = QLatin1String("Dialog is still visible after clicking the '%1' button")
.arg(dialogButton);
return false;
}
return true;
}
};
#define CREATE_DIALOG_TEST_HELPER \
DialogTestHelper<QQuickFontDialog, QQuickFontDialogImpl> dialogHelper(this, "fontDialog.qml"); \
QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); \
QVERIFY(dialogHelper.waitForWindowActive());
#define CLOSE_DIALOG(BUTTON) \
QString errorMessage; \
QVERIFY2(closePopup(&dialogHelper, BUTTON, errorMessage), qPrintable(errorMessage)); \
QTRY_VERIFY(!dialogHelper.quickDialog->isVisible());
// We don't want to fail on warnings until QTBUG-98964 is fixed,
// as we deliberately prevent deferred execution in some of the tests here,
// which causes warnings.
tst_QQuickFontDialogImpl::tst_QQuickFontDialogImpl()
: QQmlDataTest(QT_QMLTEST_DATADIR, FailOnWarningsPolicy::DoNotFailOnWarnings)
{
}
void tst_QQuickFontDialogImpl::initTestCase()
{
QCoreApplication::setAttribute(Qt::AA_DontUseNativeDialogs);
QQmlDataTest::initTestCase();
}
void tst_QQuickFontDialogImpl::defaults()
{
QTest::failOnWarning(QRegularExpression(".*"));
CREATE_DIALOG_TEST_HELPER
// Open the dialog.
QVERIFY(dialogHelper.openDialog());
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
QQuickListView *fontFamilyListView = dialogHelper.quickDialog->findChild<QQuickListView *>("familyListView");
QVERIFY(fontFamilyListView);
QQuickListView *fontStyleListView = dialogHelper.quickDialog->findChild<QQuickListView *>("styleListView");
QVERIFY(fontStyleListView);
QQuickListView *fontSizeListView = dialogHelper.quickDialog->findChild<QQuickListView *>("sizeListView");
QVERIFY(fontSizeListView);
QQuickTextField *fontFamilyTextField = dialogHelper.quickDialog->findChild<QQuickTextField *>("familyEdit");
QVERIFY(fontFamilyTextField);
QQuickTextField *fontStyleTextField = dialogHelper.quickDialog->findChild<QQuickTextField *>("styleEdit");
QVERIFY(fontStyleTextField);
// The indexes should initially be 0.
QCOMPARE(fontFamilyListView->currentIndex(), 0);
QCOMPARE(fontStyleListView->currentIndex(), 0);
QCOMPARE(fontSizeListView->currentIndex(), 0);
// Setting the family to an empty model
fontFamilyListView->setModel(QStringList());
// The listviews for font family and style should now have an empty model with indexes set to -1
QVERIFY(fontFamilyListView->model().toStringList().isEmpty());
QVERIFY(fontStyleListView->model().toStringList().isEmpty());
QCOMPARE(fontFamilyListView->currentIndex(), -1);
QCOMPARE(fontStyleListView->currentIndex(), -1);
QVERIFY(fontFamilyTextField->text().isEmpty());
QVERIFY(fontStyleTextField->text().isEmpty());
CLOSE_DIALOG("Ok");
}
void tst_QQuickFontDialogImpl::changingWritingSystem()
{
CREATE_DIALOG_TEST_HELPER
// Open the dialog.
QVERIFY(dialogHelper.openDialog());
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
QVERIFY(dialogHelper.waitForPopupWindowActiveAndPolished());
const QQuickTextEdit *sampleEdit =
dialogHelper.quickDialog->findChild<QQuickTextEdit *>("sampleEdit");
QVERIFY(sampleEdit);
QCOMPARE(sampleEdit->text(), QFontDatabase::writingSystemSample(QFontDatabase::Any));
// Check that the font family list view exist and add signal spy.
const QQuickListView *fontFamilyListView =
dialogHelper.quickDialog->findChild<QQuickListView *>("familyListView");
QVERIFY(fontFamilyListView);
QSignalSpy fontFamilyModelSpy(fontFamilyListView, SIGNAL(modelChanged()));
// Open the ComboBox's popup.
const QQuickComboBox *writingSystemComboBox = dialogHelper.quickDialog->findChild<QQuickComboBox*>();
QVERIFY(writingSystemComboBox);
const QPoint comboBoxCenterPos = writingSystemComboBox->mapToScene({ writingSystemComboBox->width() / 2, writingSystemComboBox->height() / 2 }).toPoint();
QTest::mouseClick(dialogHelper.popupWindow(), Qt::LeftButton, Qt::NoModifier, comboBoxCenterPos);
QTRY_VERIFY(writingSystemComboBox->popup()->isOpened());
// "Any" should be selected by default.
QQuickListView *comboBoxPopupListView = qobject_cast<QQuickListView*>(writingSystemComboBox->popup()->contentItem());
QVERIFY(comboBoxPopupListView);
const int anyIndex = QFontDatabase::Any;
QQuickAbstractButton *anyDelegate = qobject_cast<QQuickAbstractButton*>(findViewDelegateItem(comboBoxPopupListView, anyIndex));
QVERIFY(anyDelegate);
QCOMPARE(anyDelegate->text(), QFontDatabase::writingSystemName(QFontDatabase::Any));
QCOMPARE(fontFamilyModelSpy.size(), 0);
// Select "Japanese" from the ComboBox.
const int japaneseIndex = QFontDatabase::Japanese;
QQuickAbstractButton *japaneseDelegate = qobject_cast<QQuickAbstractButton*>(findViewDelegateItem(comboBoxPopupListView, japaneseIndex));
QVERIFY(japaneseDelegate);
QCOMPARE(japaneseDelegate->text(), QFontDatabase::writingSystemName(QFontDatabase::Japanese));
QVERIFY(clickButton(japaneseDelegate));
QTRY_VERIFY(!writingSystemComboBox->popup()->isVisible());
// Check that the contents of the font family listview changed
QCOMPARE(fontFamilyModelSpy.size(), 1);
// And that the sample text is correctly set
QCOMPARE(sampleEdit->text(), QFontDatabase::writingSystemSample(QFontDatabase::Japanese));
// Then accept it to close it.
auto dialogButtonBox = dialogHelper.quickDialog->footer()->findChild<QQuickDialogButtonBox*>();
QVERIFY(dialogButtonBox);
QQuickAbstractButton* openButton = findDialogButton(dialogButtonBox, "Ok");
QVERIFY(openButton);
QVERIFY(clickButton(openButton));
QVERIFY(!dialogHelper.dialog->isVisible());
QTRY_VERIFY(!dialogHelper.quickDialog->isVisible());
}
void tst_QQuickFontDialogImpl::clickAroundInTheFamilyListView()
{
CREATE_DIALOG_TEST_HELPER
// Open the dialog.
QVERIFY(dialogHelper.openDialog());
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
QVERIFY(dialogHelper.waitForPopupWindowActiveAndPolished());
QQuickListView *fontFamilyListView =
dialogHelper.quickDialog->findChild<QQuickListView *>("familyListView");
QVERIFY(fontFamilyListView);
const QQuickListView *fontStyleListView =
dialogHelper.quickDialog->findChild<QQuickListView *>("styleListView");
QVERIFY(fontStyleListView);
const QQuickListView *fontSizeListView =
dialogHelper.quickDialog->findChild<QQuickListView *>("sizeListView");
QVERIFY(fontSizeListView);
QSignalSpy selectedFontSpy(dialogHelper.dialog, SIGNAL(selectedFontChanged()));
QSignalSpy styleModelSpy(fontStyleListView, SIGNAL(modelChanged()));
QSignalSpy sizeModelSpy(fontSizeListView, SIGNAL(modelChanged()));
QCOMPARE(fontFamilyListView->currentIndex(), 0);
QCOMPARE(fontStyleListView->currentIndex(), 0);
QCOMPARE(fontSizeListView->currentIndex(), 0);
auto fontListModel = QFontDatabase::families(QFontDatabase::WritingSystem::Any);
fontListModel.removeIf(QFontDatabase::isPrivateFamily);
// In case the font database contains a significant number of font families
const int maxNumberOfFamiliesToTest = 10;
for (auto i = 1; i < qMin(fontListModel.size(), maxNumberOfFamiliesToTest); ++i) {
selectedFontSpy.clear();
styleModelSpy.clear();
sizeModelSpy.clear();
const QString err = QString("LOOP INDEX %1, EXPECTED %2, ACTUAL %3").arg(i);
const QFont selectedFont = dialogHelper.dialog->selectedFont();
const auto oldStyleModel = fontStyleListView->model();
const auto oldSizeModel = fontSizeListView->model();
const QString expected1 = fontListModel[i - 1], actual1 = selectedFont.family();
QVERIFY2(expected1 == actual1, qPrintable(err.arg(expected1, actual1)));
QQuickAbstractButton *fontDelegate =
qobject_cast<QQuickAbstractButton *>(findViewDelegateItem(fontFamilyListView, i));
QVERIFY2(fontDelegate, qPrintable(QString("LOOP INDEX %1").arg(i)));
QVERIFY2(clickButton(fontDelegate), qPrintable(QString("LOOP INDEX %1").arg(i)));
const QString expected2 = fontListModel[i],
actual2 = dialogHelper.dialog->selectedFont().family();
QVERIFY2(expected2 == actual2, qPrintable(err.arg(expected2, actual2).append(", FONT ").append(fontDelegate->text())));
if (QSysInfo::productType() == "opensuse-leap" && QSysInfo::productVersion() == QLatin1String("16.0") && i == 5)
QEXPECT_FAIL("", "QTBUG-142384: opensuse-leap 16.0 fails with font Adwaita Mono (selectedFontSpyCount=2 and not 1)", Continue);
const int selectedFontSpyCount = selectedFontSpy.size();
QVERIFY2(selectedFontSpyCount == 1, qPrintable(err.arg(1).arg(selectedFontSpyCount).append(", FONT ").append(fontDelegate->text())));
QVERIFY2((oldStyleModel == fontStyleListView->model()) != (styleModelSpy.size() == 1),
qPrintable(QString("LOOP INDEX %1").arg(i)));
QVERIFY2((oldSizeModel == fontSizeListView->model()) != (sizeModelSpy.size() == 1),
qPrintable(QString("LOOP INDEX %1").arg(i)));
}
CLOSE_DIALOG("Ok");
}
void tst_QQuickFontDialogImpl::settingUnderlineAndStrikeoutEffects()
{
CREATE_DIALOG_TEST_HELPER
// Open the dialog.
QVERIFY(dialogHelper.openDialog());
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
QVERIFY(dialogHelper.waitForPopupWindowActiveAndPolished());
QSignalSpy selectedFontSpy(dialogHelper.dialog, SIGNAL(selectedFontChanged()));
QQuickCheckBox *underlineCheckBox =
dialogHelper.quickDialog->findChild<QQuickCheckBox *>("underlineEffect");
QVERIFY(underlineCheckBox);
QQuickCheckBox *strikeoutCheckBox =
dialogHelper.quickDialog->findChild<QQuickCheckBox *>("strikeoutEffect");
QVERIFY(strikeoutCheckBox);
QVERIFY(!dialogHelper.dialog->selectedFont().underline());
QVERIFY(!dialogHelper.dialog->selectedFont().strikeOut());
QVERIFY(clickButton(underlineCheckBox));
QCOMPARE(selectedFontSpy.size(), 1);
QVERIFY(dialogHelper.dialog->selectedFont().underline());
QVERIFY(!dialogHelper.dialog->selectedFont().strikeOut());
QVERIFY(QQuickTest::qWaitForPolish(dialogHelper.popupWindow()));
QVERIFY(clickButton(underlineCheckBox));
QCOMPARE(selectedFontSpy.size(), 2);
QVERIFY(!dialogHelper.dialog->selectedFont().underline());
QVERIFY(!dialogHelper.dialog->selectedFont().strikeOut());
QVERIFY(QQuickTest::qWaitForPolish(dialogHelper.popupWindow()));
QVERIFY(clickButton(strikeoutCheckBox));
QCOMPARE(selectedFontSpy.size(), 3);
QVERIFY(!dialogHelper.dialog->selectedFont().underline());
QVERIFY(dialogHelper.dialog->selectedFont().strikeOut());
QVERIFY(QQuickTest::qWaitForPolish(dialogHelper.popupWindow()));
QVERIFY(clickButton(strikeoutCheckBox));
QCOMPARE(selectedFontSpy.size(), 4);
QVERIFY(!dialogHelper.dialog->selectedFont().underline());
QVERIFY(!dialogHelper.dialog->selectedFont().strikeOut());
// Then accept it to close it.
CLOSE_DIALOG("Ok");
}
void tst_QQuickFontDialogImpl::changeFontSize()
{
CREATE_DIALOG_TEST_HELPER
// Open the dialog.
QVERIFY(dialogHelper.openDialog());
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
QVERIFY(dialogHelper.waitForPopupWindowActiveAndPolished());
QQuickTextField *sizeEdit = dialogHelper.quickDialog->findChild<QQuickTextField *>("sizeEdit");
QVERIFY(sizeEdit);
QQuickListView *fontSizeListView =
dialogHelper.quickDialog->findChild<QQuickListView *>("sizeListView");
QVERIFY(fontSizeListView);
const QQuickItemDelegate *firstSizeDelegate =
qobject_cast<QQuickItemDelegate *>(findViewDelegateItem(fontSizeListView, 0));
QCOMPARE(dialogHelper.dialog->selectedFont().pointSize(), firstSizeDelegate->text().toInt());
sizeEdit->setText("15");
QCOMPARE(dialogHelper.dialog->selectedFont().pointSize(), 15);
sizeEdit->setText("22");
QCOMPARE(dialogHelper.dialog->selectedFont().pointSize(), 22);
// Then accept it to close it.
CLOSE_DIALOG("Ok");
}
void tst_QQuickFontDialogImpl::changeDialogTitle()
{
CREATE_DIALOG_TEST_HELPER
// Open the dialog.
QVERIFY(dialogHelper.openDialog());
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
const auto dialogButtonBox =
dialogHelper.quickDialog->footer()->findChild<QQuickDialogButtonBox *>();
QVERIFY(dialogButtonBox);
QQuickAbstractButton *cancelButton = findDialogButton(dialogButtonBox, "Cancel");
QVERIFY(cancelButton);
const auto *header = dialogHelper.quickDialog->header();
const QQuickLabel *titleLabel = [header]() {
if (auto *label = qobject_cast<const QQuickLabel *>(header))
return label;
return header->findChild<const QQuickLabel *>();
}();
QVERIFY(titleLabel);
QCOMPARE(titleLabel->text(), QString());
const QString newTitle1 = QLatin1String("Some random title #1");
// Dialog must be closed for the title to update
QVERIFY(clickButton(cancelButton));
QVERIFY(!dialogHelper.dialog->isVisible());
QTRY_VERIFY(!dialogHelper.quickDialog->isVisible());
dialogHelper.dialog->setTitle(newTitle1);
// Reopen the dialog
QVERIFY(dialogHelper.openDialog());
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
QVERIFY(dialogHelper.dialog->isVisible());
QTRY_VERIFY(dialogHelper.quickDialog->isVisible());
QCOMPARE(titleLabel->text(), newTitle1);
const QString newTitle2 = QLatin1String("Some random other title #2");
dialogHelper.dialog->setTitle(newTitle2);
// Shouldn't update unless you reopen the dialog
QCOMPARE(titleLabel->text(), newTitle1);
QVERIFY(clickButton(cancelButton));
QVERIFY(dialogHelper.openDialog());
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
// Should now be updated
QCOMPARE(titleLabel->text(), newTitle2);
CLOSE_DIALOG("Ok");
}
/*
Represents the expected search logic we use when the user types text into
one of the read-only text edits.
As we test against real fonts installed on the system and hence cannot use
a hard-coded list, we need this helper to ensure that the (non-trivial)
searching behavior matches what we expect.
*/
class ListSearchHelper
{
public:
ListSearchHelper(const QStringList &model)
: m_model(model)
{
}
int expectedCurrentIndexForSearch(const QString &searchText)
{
bool redo = false;
do {
m_searchText.append(searchText);
for (int i = 0; i < m_model.size(); ++i) {
if (m_model.at(i).startsWith(m_searchText, Qt::CaseInsensitive))
return i;
}
m_searchText.clear();
redo = !redo;
} while (redo);
return -1;
}
private:
QStringList m_model;
QString m_searchText;
};
void tst_QQuickFontDialogImpl::searchFamily()
{
CREATE_DIALOG_TEST_HELPER
// Open the dialog.
QVERIFY(dialogHelper.openDialog());
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
QVERIFY(dialogHelper.waitForPopupWindowActiveAndPolished());
const QQuickTextField *familyEdit =
dialogHelper.quickDialog->findChild<QQuickTextField *>("familyEdit");
QVERIFY(familyEdit);
QQuickListView *fontFamilyListView =
dialogHelper.quickDialog->findChild<QQuickListView *>("familyListView");
QVERIFY(fontFamilyListView);
const QPoint familyEditCenterPos =
familyEdit->mapToScene({ familyEdit->width() / 2, familyEdit->height() / 2 }).toPoint();
QTest::mouseClick(dialogHelper.popupWindow(), Qt::LeftButton, Qt::NoModifier, familyEditCenterPos);
QTRY_VERIFY_ACTIVE_FOCUS(familyEdit);
QSignalSpy familyListViewCurrentIndexSpy(fontFamilyListView, SIGNAL(currentIndexChanged()));
QVERIFY(familyListViewCurrentIndexSpy.isValid());
const QString alphabet("abcdefghijklmnopqrstuvwxyz");
QStringList model = QFontDatabase::families(QFontDatabase::WritingSystem::Any);
model.removeIf(QFontDatabase::isPrivateFamily);
ListSearchHelper listSearchHelper(model);
// For each letter in the alphabet, press the corresponding key
// and check that the relevant delegate item in familyListView is selected.
for (auto alphabet_it = alphabet.cbegin(); alphabet_it != alphabet.cend(); alphabet_it++) {
const int previousIndex = fontFamilyListView->currentIndex();
const char keyEntered = alphabet_it->toLatin1();
QTest::keyClick(dialogHelper.popupWindow(), keyEntered);
int expectedListViewIndex = listSearchHelper.expectedCurrentIndexForSearch(QString(keyEntered));
if (expectedListViewIndex == -1) {
// There was no match, so the currentIndex should remain unchanged.
expectedListViewIndex = previousIndex;
}
if (fontFamilyListView->currentIndex() == expectedListViewIndex) {
// Working as expected; keep testing.
continue;
}
// Get the actual text of the current delegate item and the expected text.
auto currentDelegateItem = findViewDelegateItem(fontFamilyListView, fontFamilyListView->currentIndex());
QVERIFY(currentDelegateItem);
const auto actualDelegateText = currentDelegateItem->property("text").toString();
const auto expectedDelegateText = expectedListViewIndex != -1 ? model.at(expectedListViewIndex) : "(none)";
QFAIL(qPrintable(QString::fromLatin1("Expected fontFamilyListView to"
" change its currentIndex to %1 (%2) after typing '%3', but it is %4 (%5)")
.arg(expectedListViewIndex)
.arg(expectedDelegateText)
.arg(keyEntered)
.arg(fontFamilyListView->currentIndex())
.arg(actualDelegateText)));
}
CLOSE_DIALOG("Ok");
}
void tst_QQuickFontDialogImpl::setCurrentFontFromApi()
{
CREATE_DIALOG_TEST_HELPER
QSignalSpy selectedFontSpy(dialogHelper.dialog, SIGNAL(selectedFontChanged()));
// Open the dialog.
QVERIFY(dialogHelper.openDialog());
QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
QQuickListView *fontFamilyListView =
dialogHelper.quickDialog->findChild<QQuickListView *>("familyListView");
QVERIFY(fontFamilyListView);
QQuickListView *fontStyleListView =
dialogHelper.quickDialog->findChild<QQuickListView *>("styleListView");
QVERIFY(fontStyleListView);
QQuickListView *fontSizeListView =
dialogHelper.quickDialog->findChild<QQuickListView *>("sizeListView");
QVERIFY(fontSizeListView);
QQuickTextField *fontSizeEdit =
dialogHelper.quickDialog->findChild<QQuickTextField *>("sizeEdit");
QVERIFY(fontSizeEdit);
// From when the listviews are populated
QCOMPARE(selectedFontSpy.size(), 1);
selectedFontSpy.clear();
// testing some available fonts
const auto familyModel = fontFamilyListView->model().toStringList();
int spyCounter = 0;
const int maxNumberOfFontFamilies = 10, maxNumberOfStyles = 3;
int size = 10;
int familyCounter = 0;
for (auto family = familyModel.cbegin(); family != familyModel.cend() && familyCounter < maxNumberOfFontFamilies; family++, familyCounter++)
{
const QString style = QFontDatabase::styles(*family).constFirst();
const QFont f = QFontDatabase::font(*family, style, size);
dialogHelper.dialog->setSelectedFont(f);
const int familyIndex = fontFamilyListView->currentIndex();
QVERIFY(familyIndex >= 0);
QCOMPARE(familyModel.at(familyIndex), *family);
const QStringList styleModel = fontStyleListView->model().toStringList();
QVERIFY(!styleModel.isEmpty()); // Any valid font should always have at least one style.
QCOMPARE(styleModel.at(fontStyleListView->currentIndex()), style);
QCOMPARE(fontSizeEdit->text(), QString::number(size++));
QCOMPARE(selectedFontSpy.size(), ++spyCounter);
for (int styleIt = 0; styleIt < qMin(styleModel.size(), maxNumberOfStyles); ++styleIt) {
const QString currentStyle = styleModel.at(styleIt);
const QFont f = QFontDatabase::font(*family, currentStyle, size);
dialogHelper.dialog->setSelectedFont(f);
QCOMPARE(styleModel.at(fontStyleListView->currentIndex()), currentStyle);
QCOMPARE(selectedFontSpy.size(), ++spyCounter);
}
}
CLOSE_DIALOG("Ok");
}
void tst_QQuickFontDialogImpl::checkModality_data()
{
QTest::addColumn<Qt::WindowModality>("modality");
QTest::addColumn<QFontDialogOptions::FontDialogOption>("options");
QTest::addColumn<int>("expectedRootWindowChildCount");
QTest::addColumn<int>("expectedChildWindowClickCount");
QTest::newRow("nonModal") << Qt::NonModal << QFontDialogOptions::DontUseNativeDialog << 1 << 1;
QTest::newRow("windowModal") << Qt::WindowModal << QFontDialogOptions::DontUseNativeDialog << 0 << 1;
// Verify application modal case only for the platform which supports multiple windows
if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::MultipleWindows))
QTest::newRow("applicationModal") << Qt::ApplicationModal << QFontDialogOptions::DontUseNativeDialog << 0 << 0;
}
void tst_QQuickFontDialogImpl::checkModality()
{
QFETCH(Qt::WindowModality, modality);
QFETCH(QFontDialogOptions::FontDialogOption, options);
QFETCH(int, expectedRootWindowChildCount);
QFETCH(int, expectedChildWindowClickCount);
DialogTestHelper<QQuickFontDialog, QQuickFontDialogImpl> dialogHelper(this, "checkModality.qml");
QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage());
QVERIFY(dialogHelper.waitForWindowActive());
dialogHelper.dialog->setModality(modality);
QCOMPARE(dialogHelper.dialog->modality(), modality);
dialogHelper.dialog->setOptions(options);
QCOMPARE(dialogHelper.dialog->options(), options);
OPEN_QUICK_DIALOG();
QVERIFY(dialogHelper.waitForPopupWindowActiveAndPolished());
auto *childWindow = dialogHelper.window()->property("childWindow").value<QQuickWindow *>();
QVERIFY(childWindow);
// Setting the child window transient parent as root window won't allow it to receive mouse
// events, causing WindowModal case not to be tested. Thus, resetting the transient parent.
if (modality == Qt::WindowModal)
childWindow->setTransientParent(nullptr);
const auto *rootMouseArea = dialogHelper.window()->property("rootMArea").value<QQuickMouseArea *>();
QVERIFY(rootMouseArea);
QSignalSpy rmaMouseSpy(rootMouseArea, &QQuickMouseArea::clicked);
QTest::mouseClick(dialogHelper.window(), Qt::LeftButton, Qt::NoModifier, QPoint(5, 5));
QCOMPARE(rmaMouseSpy.size(), expectedRootWindowChildCount);
const auto *childMouseArea = dialogHelper.window()->property("childMArea").value<QQuickMouseArea *>();
QVERIFY(childMouseArea);
QSignalSpy cmaMouseSpy(childMouseArea, &QQuickMouseArea::clicked);
QTest::mouseClick(childWindow, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5));
QCOMPARE(cmaMouseSpy.size(), expectedChildWindowClickCount);
}
void tst_QQuickFontDialogImpl::checkFrameless()
{
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
QSKIP("Frameless window is not supported on Android/IOS");
#endif
DialogTestHelper<QQuickFontDialog, QQuickFontDialogImpl> dialogHelper(this, "fontDialogFrameless.qml");
OPEN_QUICK_DIALOG();
QVERIFY(dialogHelper.waitForPopupWindowActiveAndPolished());
QVERIFY(dialogHelper.popupWindow()->flags().testFlag(Qt::FramelessWindowHint));
}
QTEST_QUICKDIALOGS_MAIN(tst_QQuickFontDialogImpl)
#include "tst_qquickfontdialogimpl.moc"