1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29
30#include <QtTest/QtTest>
31
32
33#include <qapplication.h>
34#include <qfontdatabase.h>
35#include <qfontinfo.h>
36#include <qtimer.h>
37#include <qmainwindow.h>
38#include <qlistview.h>
39#include "qfontdialog.h"
40#include <private/qfontdialog_p.h>
41
42QT_FORWARD_DECLARE_CLASS(QtTestEventThread)
43
44class tst_QFontDialog : public QObject
45{
46 Q_OBJECT
47
48public:
49 tst_QFontDialog();
50 virtual ~tst_QFontDialog();
51
52
53public slots:
54 void postKeyReturn();
55 void testGetFont();
56 void testSetFont();
57 void testNonStandardFontSize();
58
59public slots:
60 void initTestCase();
61 void cleanupTestCase();
62 void init();
63 void cleanup();
64private slots:
65 void defaultOkButton();
66 void setFont();
67 void task256466_wrongStyle();
68 void setNonStandardFontSize();
69#ifndef QT_NO_STYLE_STYLESHEET
70 void qtbug_41513_stylesheetStyle();
71#endif
72
73
74private:
75 void runSlotWithFailsafeTimer(const char *member);
76};
77
78tst_QFontDialog::tst_QFontDialog()
79{
80}
81
82tst_QFontDialog::~tst_QFontDialog()
83{
84}
85
86void tst_QFontDialog::initTestCase()
87{
88}
89
90void tst_QFontDialog::cleanupTestCase()
91{
92}
93
94void tst_QFontDialog::init()
95{
96}
97
98void tst_QFontDialog::cleanup()
99{
100}
101
102void tst_QFontDialog::postKeyReturn() {
103 QWidgetList list = QApplication::topLevelWidgets();
104 for (int i=0; i<list.count(); ++i) {
105 QFontDialog *dialog = qobject_cast<QFontDialog*>(object: list[i]);
106 if (dialog) {
107 QTest::keyClick( widget: list[i], key: Qt::Key_Return, modifier: Qt::NoModifier );
108 return;
109 }
110 }
111}
112
113void tst_QFontDialog::testGetFont()
114{
115#ifdef Q_OS_MAC
116 QEXPECT_FAIL("", "Sending QTest::keyClick to OSX font dialog helper fails, see QTBUG-24321", Continue);
117#endif
118 bool ok = false;
119 QTimer::singleShot(msec: 2000, receiver: this, SLOT(postKeyReturn()));
120 QFontDialog::getFont(ok: &ok);
121 QVERIFY(ok);
122}
123
124void tst_QFontDialog::runSlotWithFailsafeTimer(const char *member)
125{
126 // FailSafeTimer quits the nested event loop if the dialog closing doesn't do it.
127 QTimer failSafeTimer;
128 failSafeTimer.setInterval(4000);
129 failSafeTimer.setSingleShot(true);
130 connect(sender: &failSafeTimer, SIGNAL(timeout()), qApp, SLOT(quit()));
131 failSafeTimer.start();
132
133 QTimer::singleShot(msec: 0, receiver: this, member);
134 qApp->exec();
135
136 // FailSafeTimer stops once it goes out of scope.
137}
138
139void tst_QFontDialog::defaultOkButton()
140{
141 runSlotWithFailsafeTimer(SLOT(testGetFont()));
142}
143
144void tst_QFontDialog::testSetFont()
145{
146 bool ok = false;
147#if defined Q_OS_HPUX
148 QString fontName = "Courier";
149 int fontSize = 25;
150#elif defined Q_OS_AIX
151 QString fontName = "Charter";
152 int fontSize = 13;
153#else
154 QString fontName = "Arial";
155 int fontSize = 24;
156#endif
157 QFont f1(fontName, fontSize);
158 f1.setPixelSize(QFontInfo(f1).pixelSize());
159 QTimer::singleShot(msec: 2000, receiver: this, SLOT(postKeyReturn()));
160 QFont f2 = QFontDialog::getFont(ok: &ok, initial: f1);
161 QCOMPARE(QFontInfo(f2).pointSize(), QFontInfo(f1).pointSize());
162}
163
164void tst_QFontDialog::setFont()
165{
166 /* The font should be the same before as it is after if nothing changed
167 while the font dialog was open.
168 Task #27662
169 */
170 runSlotWithFailsafeTimer(SLOT(testSetFont()));
171}
172
173
174class FriendlyFontDialog : public QFontDialog
175{
176 friend class tst_QFontDialog;
177 Q_DECLARE_PRIVATE(QFontDialog)
178};
179
180void tst_QFontDialog::task256466_wrongStyle()
181{
182 if (QGuiApplication::platformName().startsWith(s: QLatin1String("wayland"), cs: Qt::CaseInsensitive))
183 QSKIP("Wayland: This freezes. Figure out why.");
184
185 QFontDatabase fdb;
186 FriendlyFontDialog dialog;
187 dialog.setOption(option: QFontDialog::DontUseNativeDialog);
188 QListView *familyList = reinterpret_cast<QListView*>(dialog.d_func()->familyList);
189 QListView *styleList = reinterpret_cast<QListView*>(dialog.d_func()->styleList);
190 QListView *sizeList = reinterpret_cast<QListView*>(dialog.d_func()->sizeList);
191 for (int i = 0; i < familyList->model()->rowCount(); ++i) {
192 QModelIndex currentFamily = familyList->model()->index(row: i, column: 0);
193 familyList->setCurrentIndex(currentFamily);
194 int expectedSize = sizeList->currentIndex().data().toInt();
195 const QFont current = dialog.currentFont(),
196 expected = fdb.font(family: currentFamily.data().toString(),
197 style: styleList->currentIndex().data().toString(), pointSize: expectedSize);
198 QCOMPARE(current.family(), expected.family());
199 QCOMPARE(current.style(), expected.style());
200 if (expectedSize == 0 && !QFontDatabase().isScalable(family: current.family(), style: current.styleName()))
201 QEXPECT_FAIL("", "QTBUG-53299: Smooth sizes for unscalable font contains unsupported size", Continue);
202 QCOMPARE(current.pointSizeF(), expected.pointSizeF());
203 }
204}
205
206void tst_QFontDialog::setNonStandardFontSize()
207{
208 runSlotWithFailsafeTimer(SLOT(testNonStandardFontSize()));
209}
210#ifndef QT_NO_STYLE_STYLESHEET
211static const QString offendingStyleSheet = QStringLiteral("* { font-family: \"QtBidiTestFont\"; }");
212
213void tst_QFontDialog::qtbug_41513_stylesheetStyle()
214{
215 if (QFontDatabase::addApplicationFont(QFINDTESTDATA("test.ttf")) < 0)
216 QSKIP("Test fonts not found.");
217 if (QFontDatabase::addApplicationFont(QFINDTESTDATA("testfont.ttf")) < 0)
218 QSKIP("Test fonts not found.");
219 QFont testFont = QFont(QStringLiteral("QtsSpecialTestFont"));
220 qApp->setStyleSheet(offendingStyleSheet);
221 bool accepted = false;
222 QTimer::singleShot(msec: 2000, receiver: this, SLOT(postKeyReturn()));
223 QFont resultFont = QFontDialog::getFont(ok: &accepted, initial: testFont,
224 parent: QApplication::activeWindow(),
225 title: QLatin1String("QFontDialog - Stylesheet Test"),
226 options: QFontDialog::DontUseNativeDialog);
227 QVERIFY(accepted);
228
229 // The fontdialog sets the styleName, when the fontdatabase knows the style name.
230 resultFont.setStyleName(testFont.styleName());
231 testFont.setFamilies(QStringList(testFont.family()));
232 QCOMPARE(resultFont, testFont);
233
234 // reset stylesheet
235 qApp->setStyleSheet(QString());
236}
237#endif // QT_NO_STYLE_STYLESHEET
238
239void tst_QFontDialog::testNonStandardFontSize()
240{
241 QList<int> standardSizesList = QFontDatabase::standardSizes();
242 int nonStandardFontSize;
243 if (!standardSizesList.isEmpty()) {
244 nonStandardFontSize = standardSizesList.at(i: standardSizesList.count()-1); // get the maximum standard size.
245 nonStandardFontSize += 1; // the increment of 1 to mock a non-standard font size.
246 } else {
247 QSKIP("QFontDatabase::standardSizes() is empty.");
248 }
249
250 QFont testFont;
251 testFont.setPointSize(nonStandardFontSize);
252
253 bool accepted = false;
254 QTimer::singleShot(msec: 2000, receiver: this, SLOT(postKeyReturn()));
255 QFont resultFont = QFontDialog::getFont(ok: &accepted, initial: testFont,
256 parent: QApplication::activeWindow(),
257 title: QLatin1String("QFontDialog - NonStandardFontSize Test"),
258 options: QFontDialog::DontUseNativeDialog);
259 QVERIFY(accepted);
260
261 if (accepted)
262 QCOMPARE(testFont.pointSize(), resultFont.pointSize());
263 else
264 QWARN("Fail using a non-standard font size.");
265}
266
267QTEST_MAIN(tst_QFontDialog)
268#include "tst_qfontdialog.moc"
269

source code of qtbase/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp