summaryrefslogtreecommitdiffstats
path: root/tests/auto/widgets/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/widgets/widgets')
-rw-r--r--tests/auto/widgets/widgets/CMakeLists.txt18
-rw-r--r--tests/auto/widgets/widgets/qabstractbutton/CMakeLists.txt12
-rw-r--r--tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp124
-rw-r--r--tests/auto/widgets/widgets/qabstractscrollarea/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/widgets/qabstractscrollarea/tst_qabstractscrollarea.cpp82
-rw-r--r--tests/auto/widgets/widgets/qabstractslider/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp77
-rw-r--r--tests/auto/widgets/widgets/qabstractspinbox/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/widgets/qabstractspinbox/tst_qabstractspinbox.cpp116
-rw-r--r--tests/auto/widgets/widgets/qbuttongroup/CMakeLists.txt12
-rw-r--r--tests/auto/widgets/widgets/qbuttongroup/tst_qbuttongroup.cpp77
-rw-r--r--tests/auto/widgets/widgets/qcalendarwidget/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/widgets/qcalendarwidget/tst_qcalendarwidget.cpp42
-rw-r--r--tests/auto/widgets/widgets/qcheckbox/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/widgets/qcheckbox/tst_qcheckbox.cpp96
-rw-r--r--tests/auto/widgets/widgets/qcombobox/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp570
-rw-r--r--tests/auto/widgets/widgets/qcommandlinkbutton/CMakeLists.txt12
-rw-r--r--tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp62
-rw-r--r--tests/auto/widgets/widgets/qdatetimeedit/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp418
-rw-r--r--tests/auto/widgets/widgets/qdial/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/widgets/qdial/tst_qdial.cpp63
-rw-r--r--tests/auto/widgets/widgets/qdialogbuttonbox/CMakeLists.txt12
-rw-r--r--tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp274
-rw-r--r--tests/auto/widgets/widgets/qdockwidget/BLACKLIST33
-rw-r--r--tests/auto/widgets/widgets/qdockwidget/CMakeLists.txt12
-rw-r--r--tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp1134
-rw-r--r--tests/auto/widgets/widgets/qdoublespinbox/CMakeLists.txt12
-rw-r--r--tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp84
-rw-r--r--tests/auto/widgets/widgets/qfocusframe/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/widgets/qfocusframe/tst_qfocusframe.cpp31
-rw-r--r--tests/auto/widgets/widgets/qfontcombobox/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/widgets/qfontcombobox/tst_qfontcombobox.cpp94
-rw-r--r--tests/auto/widgets/widgets/qframe/BLACKLIST3
-rw-r--r--tests/auto/widgets/widgets/qframe/CMakeLists.txt13
-rw-r--r--tests/auto/widgets/widgets/qframe/tst_qframe.cpp42
-rw-r--r--tests/auto/widgets/widgets/qgroupbox/CMakeLists.txt13
-rw-r--r--tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp74
-rw-r--r--tests/auto/widgets/widgets/qkeysequenceedit/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/widgets/qkeysequenceedit/tst_qkeysequenceedit.cpp112
-rw-r--r--tests/auto/widgets/widgets/qlabel/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/acc_01/res_Windows_data0.qsnapbin328 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/acc_01/res_Windows_win32_data0.qsnapbin330 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data0.qsnapbin322 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data1.qsnapbin328 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data10.qsnapbin330 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data2.qsnapbin324 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data3.qsnapbin320 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data4.qsnapbin322 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data5.qsnapbin328 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data6.qsnapbin330 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data7.qsnapbin318 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data8.qsnapbin324 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data9.qsnapbin332 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data0.qsnapbin316 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data1.qsnapbin322 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data10.qsnapbin324 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data2.qsnapbin318 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data3.qsnapbin314 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data4.qsnapbin316 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data5.qsnapbin322 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data6.qsnapbin324 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data7.qsnapbin312 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data8.qsnapbin318 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data9.qsnapbin326 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data0.qsnapbin318 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data1.qsnapbin324 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data10.qsnapbin326 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data2.qsnapbin320 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data3.qsnapbin316 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data4.qsnapbin318 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data5.qsnapbin324 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data6.qsnapbin326 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data7.qsnapbin314 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data8.qsnapbin320 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data9.qsnapbin328 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Motif_data0.qsnapbin344 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Motif_data1.qsnapbin346 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Motif_data2.qsnapbin346 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_data0.qsnapbin338 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_data1.qsnapbin340 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_data2.qsnapbin340 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_win32_data0.qsnapbin340 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_win32_data1.qsnapbin342 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_win32_data2.qsnapbin342 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setPixmap/Vpix_Motif_data0.qsnapbin405 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setPixmap/Vpix_Windows_data0.qsnapbin399 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setPixmap/Vpix_Windows_win32_data0.qsnapbin397 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setPixmap/empty_Motif_data0.qsnapbin257 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setPixmap/empty_Windows_data0.qsnapbin251 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setPixmap/empty_Windows_win32_data0.qsnapbin249 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setPixmap/scaledVpix_Motif_data0.qsnapbin1040 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setPixmap/scaledVpix_Windows_data0.qsnapbin1034 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setPixmap/scaledVpix_Windows_win32_data0.qsnapbin984 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setText/res_Motif_data0.qsnapbin352 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setText/res_Motif_data1.qsnapbin398 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setText/res_Motif_data2.qsnapbin448 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setText/res_Motif_data3.qsnapbin744 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_data0.qsnapbin346 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_data1.qsnapbin392 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_data2.qsnapbin442 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_data3.qsnapbin738 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_win32_data0.qsnapbin344 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_win32_data1.qsnapbin390 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_win32_data2.qsnapbin440 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_win32_data3.qsnapbin736 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp232
-rw-r--r--tests/auto/widgets/widgets/qlcdnumber/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/widgets/qlcdnumber/tst_qlcdnumber.cpp29
-rw-r--r--tests/auto/widgets/widgets/qlineedit/BLACKLIST6
-rw-r--r--tests/auto/widgets/widgets/qlineedit/CMakeLists.txt13
-rw-r--r--tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp347
-rw-r--r--tests/auto/widgets/widgets/qmainwindow/BLACKLIST2
-rw-r--r--tests/auto/widgets/widgets/qmainwindow/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp227
-rw-r--r--tests/auto/widgets/widgets/qmdiarea/BLACKLIST8
-rw-r--r--tests/auto/widgets/widgets/qmdiarea/CMakeLists.txt18
-rw-r--r--tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp368
-rw-r--r--tests/auto/widgets/widgets/qmdisubwindow/CMakeLists.txt13
-rw-r--r--tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp106
-rw-r--r--tests/auto/widgets/widgets/qmenu/BLACKLIST8
-rw-r--r--tests/auto/widgets/widgets/qmenu/CMakeLists.txt14
-rw-r--r--tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp223
-rw-r--r--tests/auto/widgets/widgets/qmenu/tst_qmenu_mac.mm29
-rw-r--r--tests/auto/widgets/widgets/qmenubar/BLACKLIST7
-rw-r--r--tests/auto/widgets/widgets/qmenubar/CMakeLists.txt14
-rw-r--r--tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp323
-rw-r--r--tests/auto/widgets/widgets/qmenubar/tst_qmenubar_mac.mm29
-rw-r--r--tests/auto/widgets/widgets/qopenglwidget/BLACKLIST6
-rw-r--r--tests/auto/widgets/widgets/qopenglwidget/CMakeLists.txt13
-rw-r--r--tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp538
-rw-r--r--tests/auto/widgets/widgets/qplaintextedit/BLACKLIST15
-rw-r--r--tests/auto/widgets/widgets/qplaintextedit/CMakeLists.txt13
-rw-r--r--tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp245
-rw-r--r--tests/auto/widgets/widgets/qprogressbar/CMakeLists.txt12
-rw-r--r--tests/auto/widgets/widgets/qprogressbar/tst_qprogressbar.cpp33
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/CMakeLists.txt13
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/testdata/setEnabled/disabled_Windows_win32_data0.qsnapbin890 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/testdata/setEnabled/enabled_Motif_data0.qsnapbin758 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/testdata/setEnabled/enabled_Windows_data0.qsnapbin725 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/testdata/setEnabled/enabled_Windows_win32_data0.qsnapbin735 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/testdata/setPixmap/Vpix_Motif_data0.qsnapbin829 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/testdata/setPixmap/Vpix_Windows_data0.qsnapbin796 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/testdata/setPixmap/Vpix_Windows_win32_data0.qsnapbin796 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/testdata/setText/simple_Motif_data0.qsnapbin742 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/testdata/setText/simple_Windows_data0.qsnapbin709 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/testdata/setText/simple_Windows_win32_data0.qsnapbin719 -> 0 bytes
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp429
-rw-r--r--tests/auto/widgets/widgets/qradiobutton/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/widgets/qradiobutton/tst_qradiobutton.cpp29
-rw-r--r--tests/auto/widgets/widgets/qrhiwidget/CMakeLists.txt25
-rw-r--r--tests/auto/widgets/widgets/qrhiwidget/data/simple.frag8
-rw-r--r--tests/auto/widgets/widgets/qrhiwidget/data/simple.frag.qsbbin0 -> 724 bytes
-rw-r--r--tests/auto/widgets/widgets/qrhiwidget/data/simple.vert8
-rw-r--r--tests/auto/widgets/widgets/qrhiwidget/data/simple.vert.qsbbin0 -> 783 bytes
-rw-r--r--tests/auto/widgets/widgets/qrhiwidget/tst_qrhiwidget.cpp834
-rw-r--r--tests/auto/widgets/widgets/qscrollarea/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/widgets/qscrollarea/tst_qscrollarea.cpp29
-rw-r--r--tests/auto/widgets/widgets/qscrollbar/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp44
-rw-r--r--tests/auto/widgets/widgets/qsizegrip/CMakeLists.txt13
-rw-r--r--tests/auto/widgets/widgets/qsizegrip/tst_qsizegrip.cpp29
-rw-r--r--tests/auto/widgets/widgets/qslider/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/widgets/qslider/tst_qslider.cpp29
-rw-r--r--tests/auto/widgets/widgets/qspinbox/BLACKLIST2
-rw-r--r--tests/auto/widgets/widgets/qspinbox/CMakeLists.txt12
-rw-r--r--tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp108
-rw-r--r--tests/auto/widgets/widgets/qsplashscreen/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/widgets/qsplashscreen/tst_qsplashscreen.cpp47
-rw-r--r--tests/auto/widgets/widgets/qsplitter/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp144
-rw-r--r--tests/auto/widgets/widgets/qstackedwidget/CMakeLists.txt12
-rw-r--r--tests/auto/widgets/widgets/qstackedwidget/tst_qstackedwidget.cpp33
-rw-r--r--tests/auto/widgets/widgets/qstatusbar/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp79
-rw-r--r--tests/auto/widgets/widgets/qtabbar/BLACKLIST2
-rw-r--r--tests/auto/widgets/widgets/qtabbar/CMakeLists.txt12
-rw-r--r--tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp731
-rw-r--r--tests/auto/widgets/widgets/qtabwidget/CMakeLists.txt13
-rw-r--r--tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp123
-rw-r--r--tests/auto/widgets/widgets/qtextbrowser/CMakeLists.txt12
-rw-r--r--tests/auto/widgets/widgets/qtextbrowser/tst_qtextbrowser.cpp91
-rw-r--r--tests/auto/widgets/widgets/qtextedit/CMakeLists.txt13
-rw-r--r--tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp308
-rw-r--r--tests/auto/widgets/widgets/qtoolbar/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/widgets/qtoolbar/tst_qtoolbar.cpp191
-rw-r--r--tests/auto/widgets/widgets/qtoolbox/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/widgets/qtoolbox/tst_qtoolbox.cpp29
-rw-r--r--tests/auto/widgets/widgets/qtoolbutton/CMakeLists.txt12
-rw-r--r--tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp91
191 files changed, 7132 insertions, 3291 deletions
diff --git a/tests/auto/widgets/widgets/CMakeLists.txt b/tests/auto/widgets/widgets/CMakeLists.txt
index c64b86b3de..eb44f3d103 100644
--- a/tests/auto/widgets/widgets/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/CMakeLists.txt
@@ -1,4 +1,5 @@
-# Generated from widgets.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
add_subdirectory(qabstractbutton)
add_subdirectory(qabstractscrollarea)
@@ -28,6 +29,7 @@ add_subdirectory(qscrollbar)
add_subdirectory(qsizegrip)
add_subdirectory(qslider)
add_subdirectory(qspinbox)
+add_subdirectory(qsplashscreen)
add_subdirectory(qsplitter)
add_subdirectory(qstackedwidget)
add_subdirectory(qstatusbar)
@@ -46,17 +48,15 @@ endif()
if(QT_FEATURE_shortcut)
add_subdirectory(qkeysequenceedit)
endif()
+add_subdirectory(qmenu)
+add_subdirectory(qlineedit)
if(NOT ANDROID)
- # QTBUG-87417 # special case
- add_subdirectory(qlineedit)
- # QTBUG-87420 # special case
+ # QTBUG-87420
add_subdirectory(qmdiarea)
- # QTBUG-87671 # special case
- add_subdirectory(qmenu)
- # QTBUG-87421 # special case
+ # QTBUG-87421
add_subdirectory(qmenubar)
endif()
-# QTBUG-87671 # special case
-if(QT_FEATURE_opengl AND NOT ANDROID)
+if(QT_FEATURE_opengl)
add_subdirectory(qopenglwidget)
endif()
+add_subdirectory(qrhiwidget)
diff --git a/tests/auto/widgets/widgets/qabstractbutton/CMakeLists.txt b/tests/auto/widgets/widgets/qabstractbutton/CMakeLists.txt
index d192549f94..883614fc04 100644
--- a/tests/auto/widgets/widgets/qabstractbutton/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qabstractbutton/CMakeLists.txt
@@ -1,14 +1,22 @@
-# Generated from qabstractbutton.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qabstractbutton Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qabstractbutton LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qabstractbutton
SOURCES
tst_qabstractbutton.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::GuiPrivate
Qt::Widgets
+ Qt::WidgetsPrivate
)
diff --git a/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp b/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
index 878647f4a4..dc5c42513c 100644
--- a/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
+++ b/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.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>
@@ -42,6 +17,9 @@
#include <private/qguiapplication_p.h>
#include <qpa/qplatformintegration.h>
+#include <qpa/qplatformtheme.h>
+
+#include <QtWidgets/private/qapplication_p.h>
class tst_QAbstractButton : public QObject
{
@@ -81,6 +59,8 @@ private slots:
void keyNavigation();
#endif
+ void buttonPressKeys();
+
protected slots:
void onClicked();
void onToggled( bool on );
@@ -276,7 +256,13 @@ void tst_QAbstractButton::setAutoRepeat()
QCOMPARE(press_count, click_count);
QVERIFY(click_count > 1);
break;
- case 4:
+ case 4: {
+ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
+ ->themeHint(QPlatformTheme::ButtonPressKeys)
+ .value<QList<Qt::Key>>();
+ if (buttonPressKeys.contains(Qt::Key_Enter)) {
+ QSKIP("platform theme has Key_Enter in ButtonPressKeys");
+ }
// check that pressing ENTER has no effect when autorepeat is false
testWidget->setDown( false );
testWidget->setAutoRepeat( false );
@@ -293,7 +279,14 @@ void tst_QAbstractButton::setAutoRepeat()
QVERIFY( click_count == 0 );
break;
- case 5:
+ }
+ case 5: {
+ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
+ ->themeHint(QPlatformTheme::ButtonPressKeys)
+ .value<QList<Qt::Key>>();
+ if (buttonPressKeys.contains(Qt::Key_Enter)) {
+ QSKIP("platform theme has Key_Enter in ButtonPressKeys");
+ }
// check that pressing ENTER has no effect when autorepeat is true
testWidget->setDown( false );
testWidget->setAutoRepeat( true );
@@ -311,6 +304,7 @@ void tst_QAbstractButton::setAutoRepeat()
QVERIFY( click_count == 0 );
break;
+ }
case 6:
// verify autorepeat is off by default.
MyButton tmp( 0);
@@ -486,7 +480,7 @@ void tst_QAbstractButton::setShortcut()
QKeySequence seq( Qt::Key_A );
testWidget->setShortcut( seq );
- QApplication::setActiveWindow(testWidget);
+ QApplicationPrivate::setActiveWindow(testWidget);
testWidget->activateWindow();
// must be active to get shortcuts
QVERIFY(QTest::qWaitForWindowActive(testWidget));
@@ -514,11 +508,34 @@ void tst_QAbstractButton::setShortcut()
void tst_QAbstractButton::animateClick()
{
- testWidget->animateClick();
- QVERIFY( testWidget->isDown() );
- qApp->processEvents();
- QVERIFY( testWidget->isDown() );
- QTRY_VERIFY( !testWidget->isDown() );
+ MyButton button;
+ QSignalSpy pressedSpy(&button, &QAbstractButton::pressed);
+ QSignalSpy releasedSpy(&button, &QAbstractButton::released);
+ QSignalSpy clickedSpy(&button, &QAbstractButton::clicked);
+
+ QElapsedTimer elapsed;
+ elapsed.start();
+ button.animateClick();
+
+ QVERIFY(button.isDown());
+ QCOMPARE(pressedSpy.size(), 1);
+ QCOMPARE(releasedSpy.size(), 0);
+ QCOMPARE(clickedSpy.size(), 0);
+ qApp->processEvents(QEventLoop::AllEvents, 10);
+ // QAbstractButton starts a 100ms timer which performs the click. If it
+ // took more than 100ms to get here, then the button might no longer be down.
+ if (elapsed.elapsed() < 100) {
+ QVERIFY(button.isDown());
+ QCOMPARE(pressedSpy.size(), 1);
+ QCOMPARE(releasedSpy.size(), 0);
+ QCOMPARE(clickedSpy.size(), 0);
+ }
+ QTRY_VERIFY(!button.isDown());
+ // but once the button has been clicked, it must have taken at least 100ms
+ QVERIFY(elapsed.elapsed() >= 100);
+ QCOMPARE(pressedSpy.size(), 1);
+ QCOMPARE(releasedSpy.size(), 1);
+ QCOMPARE(clickedSpy.size(), 1);
}
#if QT_CONFIG(shortcut)
@@ -541,9 +558,9 @@ void tst_QAbstractButton::shortcutEvents()
QTest::qWait(1000); // ensure animate timer is expired
- QCOMPARE(pressedSpy.count(), 3);
- QCOMPARE(releasedSpy.count(), 3);
- QCOMPARE(clickedSpy.count(), 3);
+ QCOMPARE(pressedSpy.size(), 3);
+ QCOMPARE(releasedSpy.size(), 3);
+ QCOMPARE(clickedSpy.size(), 3);
}
#endif // QT_CONFIG(shortcut)
@@ -585,26 +602,26 @@ void tst_QAbstractButton::mouseReleased() // QTBUG-53244
QSignalSpy spyRelease(&button, &QAbstractButton::released);
QTest::mousePress(&button, Qt::LeftButton);
- QCOMPARE(spyPress.count(), 1);
+ QCOMPARE(spyPress.size(), 1);
QCOMPARE(button.isDown(), true);
- QCOMPARE(spyRelease.count(), 0);
+ QCOMPARE(spyRelease.size(), 0);
QTest::mouseClick(&button, Qt::RightButton);
- QCOMPARE(spyPress.count(), 1);
+ QCOMPARE(spyPress.size(), 1);
QCOMPARE(button.isDown(), true);
- QCOMPARE(spyRelease.count(), 0);
+ QCOMPARE(spyRelease.size(), 0);
QPointF posOutOfWidget = QPointF(30, 30);
QMouseEvent me(QEvent::MouseMove,
- posOutOfWidget, Qt::NoButton,
- Qt::MouseButtons(Qt::LeftButton),
- Qt::NoModifier); // mouse press and move
+ posOutOfWidget, button.mapToGlobal(posOutOfWidget),
+ Qt::NoButton, Qt::MouseButtons(Qt::LeftButton),
+ Qt::NoModifier); // mouse press and move
qApp->sendEvent(&button, &me);
// should emit released signal once mouse is dragging out of boundary
- QCOMPARE(spyPress.count(), 1);
+ QCOMPARE(spyPress.size(), 1);
QCOMPARE(button.isDown(), false);
- QCOMPARE(spyRelease.count(), 1);
+ QCOMPARE(spyRelease.size(), 1);
}
#ifdef QT_KEYPAD_NAVIGATION
@@ -624,7 +641,7 @@ void tst_QAbstractButton::keyNavigation()
}
widget.show();
- qApp->setActiveWindow(&widget);
+ QApplicationPrivate::setActiveWindow(&widget);
widget.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&widget));
@@ -664,5 +681,16 @@ void tst_QAbstractButton::keyNavigation()
}
#endif
+void tst_QAbstractButton::buttonPressKeys()
+{
+ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
+ ->themeHint(QPlatformTheme::ButtonPressKeys)
+ .value<QList<Qt::Key>>();
+ for (uint i = 0; i < buttonPressKeys.size(); ++i) {
+ QTest::keyClick(testWidget, buttonPressKeys[i]);
+ QCOMPARE(click_count, i + 1);
+ }
+}
+
QTEST_MAIN(tst_QAbstractButton)
#include "tst_qabstractbutton.moc"
diff --git a/tests/auto/widgets/widgets/qabstractscrollarea/CMakeLists.txt b/tests/auto/widgets/widgets/qabstractscrollarea/CMakeLists.txt
index d756d28952..ac1d8ad54a 100644
--- a/tests/auto/widgets/widgets/qabstractscrollarea/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qabstractscrollarea/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qabstractscrollarea.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qabstractscrollarea Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qabstractscrollarea LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qabstractscrollarea
SOURCES
tst_qabstractscrollarea.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
)
diff --git a/tests/auto/widgets/widgets/qabstractscrollarea/tst_qabstractscrollarea.cpp b/tests/auto/widgets/widgets/qabstractscrollarea/tst_qabstractscrollarea.cpp
index 9d7cc484cd..fa1f799855 100644
--- a/tests/auto/widgets/widgets/qabstractscrollarea/tst_qabstractscrollarea.cpp
+++ b/tests/auto/widgets/widgets/qabstractscrollarea/tst_qabstractscrollarea.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,6 +13,7 @@
#include <qwidget.h>
#include <qdialog.h>
#include <qscroller.h>
+#include <qstyle.h>
class tst_QAbstractScrollArea : public QObject
{
@@ -59,6 +35,7 @@ private slots:
void margins();
void resizeWithOvershoot();
+ void sizeHint();
};
tst_QAbstractScrollArea::tst_QAbstractScrollArea()
@@ -433,5 +410,56 @@ void tst_QAbstractScrollArea::resizeWithOvershoot()
QTRY_COMPARE(scrollArea.viewport()->pos(), originAtRest);
}
+void tst_QAbstractScrollArea::sizeHint()
+{
+ class ScrollArea : public QAbstractScrollArea
+ {
+ public:
+ QSize viewportSizeHint() const override { return {200, 200}; }
+ } scrollArea;
+ // We cannot reliable test the impact of the scrollbars on the size hint
+ // if the style uses transient scrollbars, so use the class Windows style.
+ const QString defaultStyle = QApplication::style()->name();
+ QApplication::setStyle("Windows");
+ auto resetStyle = qScopeGuard([defaultStyle]{
+ QApplication::setStyle(defaultStyle);
+ });
+ scrollArea.setFrameShape(QFrame::NoFrame);
+ scrollArea.setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
+ scrollArea.show();
+
+ QSize sizeHint = scrollArea.sizeHint();
+ QCOMPARE(sizeHint, scrollArea.viewportSizeHint());
+
+ scrollArea.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+ scrollArea.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+ const QSize sizeHintWithScrollBars = scrollArea.sizeHint();
+ QTRY_COMPARE_GT(sizeHintWithScrollBars.width(), sizeHint.width());
+ QTRY_COMPARE_GT(sizeHintWithScrollBars.height(), sizeHint.height());
+
+ sizeHint = scrollArea.sizeHint();
+
+ // whether the scroll area itself is visible or not should not influence
+ // the size hint
+ scrollArea.hide();
+ QCOMPARE(scrollArea.sizeHint(), sizeHint);
+ scrollArea.show();
+ QCOMPARE(scrollArea.sizeHint(), sizeHint);
+
+ scrollArea.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ scrollArea.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+
+ QCOMPARE(scrollArea.sizeHint(), scrollArea.viewportSizeHint());
+
+ scrollArea.setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ scrollArea.setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+
+ scrollArea.verticalScrollBar()->setRange(0, 1);
+ scrollArea.horizontalScrollBar()->setRange(0, 1);
+ scrollArea.resize(sizeHint / 2);
+ QApplication::processEvents(); // trigger lazy layout process
+ QCOMPARE(scrollArea.sizeHint(), sizeHintWithScrollBars);
+}
+
QTEST_MAIN(tst_QAbstractScrollArea)
#include "tst_qabstractscrollarea.moc"
diff --git a/tests/auto/widgets/widgets/qabstractslider/CMakeLists.txt b/tests/auto/widgets/widgets/qabstractslider/CMakeLists.txt
index 37c725c391..711c73931d 100644
--- a/tests/auto/widgets/widgets/qabstractslider/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qabstractslider/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qabstractslider.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qabstractslider Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qabstractslider LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qabstractslider
SOURCES
tst_qabstractslider.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::TestPrivate
Qt::Widgets
diff --git a/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp b/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp
index 7ab609a7ca..9be41ad799 100644
--- a/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp
+++ b/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.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>
@@ -1484,7 +1459,7 @@ void tst_QAbstractSlider::keyPressed()
slider->setOrientation(Qt::Horizontal);
slider->setInvertedAppearance(invertedAppearance);
slider->setInvertedControls(invertedControls);
- for (int i=0;i<keySequence.count();i++) {
+ for (int i=0;i<keySequence.size();i++) {
QTest::keyClick(slider, keySequence.at(i));
}
QCOMPARE(slider->sliderPosition(), expectedSliderPosition);
@@ -1691,8 +1666,8 @@ void tst_QAbstractSlider::wheelEvent()
#endif
QCOMPARE(slider->sliderPosition(),expectedSliderPosition);
int expectedSignalCount = (initialSliderPosition == expectedSliderPosition) ? 0 : 1;
- QCOMPARE(spy1.count(), expectedSignalCount);
- QCOMPARE(spy2.count(), expectedSignalCount);
+ QCOMPARE(spy1.size(), expectedSignalCount);
+ QCOMPARE(spy2.size(), expectedSignalCount);
if (expectedSignalCount)
QVERIFY(actionTriggeredTimeStamp < valueChangedTimeStamp);
}
@@ -1839,9 +1814,9 @@ void tst_QAbstractSlider::sliderPressedReleased()
QTest::mousePress(slider, Qt::LeftButton, {},
QPoint(rect.center().x() + 2, rect.center().y() + 2));
- QCOMPARE(spy1.count(), expectedCount);
+ QCOMPARE(spy1.size(), expectedCount);
QTest::mouseRelease(slider, Qt::LeftButton, {}, rect.center());
- QCOMPARE(spy2.count(), expectedCount);
+ QCOMPARE(spy2.size(), expectedCount);
delete slider;
}
@@ -1910,7 +1885,7 @@ void tst_QAbstractSlider::sliderMoved()
slider->setMaximum(maximum);
slider->setSliderDown(sliderDown);
slider->setSliderPosition(position);
- QCOMPARE(spy.count(), expectedCount);
+ QCOMPARE(spy.size(), expectedCount);
delete slider;
}
@@ -1982,7 +1957,7 @@ void tst_QAbstractSlider::rangeChanged()
slider.setRange(minimum, maximum);
QSignalSpy spy(&slider, SIGNAL(rangeChanged(int,int)));
slider.setRange(newMin, newMax);
- QCOMPARE(spy.count(), expectedCount);
+ QCOMPARE(spy.size(), expectedCount);
}
void tst_QAbstractSlider::setSliderPosition_data()
@@ -2021,8 +1996,8 @@ void tst_QAbstractSlider::setSliderPosition()
QSignalSpy spy2(slider, SIGNAL(valueChanged(int)));
slider->setSliderPosition(targetPosition);
QCOMPARE(slider->sliderPosition(), targetPosition);
- QCOMPARE(spy1.count(), down ? 1 : 0);
- QCOMPARE(spy2.count(), tracking ? 1 : 0);
+ QCOMPARE(spy1.size(), down ? 1 : 0);
+ QCOMPARE(spy2.size(), tracking ? 1 : 0);
QCOMPARE(slider->value(), tracking ? targetPosition : initialValue);
if (tracking && down)
QVERIFY(sliderMovedTimeStamp < valueChangedTimeStamp);
@@ -2046,17 +2021,21 @@ void tst_QAbstractSlider::setValue()
slider->setRange(minimum, maximum);
slider->setSliderDown(down);
slider->setValue(49); // to force a valueChanged() below
- QSignalSpy spy1(slider, SIGNAL(sliderMoved(int)));
- QSignalSpy spy2(slider, SIGNAL(valueChanged(int)));
- QSignalSpy spy3(slider, SIGNAL(actionTriggered(int)));
+ QSignalSpy spy1(slider, &QAbstractSlider::sliderMoved);
+ QSignalSpy spy2(slider, &QAbstractSlider::valueChanged);
+ QSignalSpy spy3(slider, &QAbstractSlider::actionTriggered);
slider->setValue(50);
- QCOMPARE(spy1.count(), down ? 1 : 0);
- QCOMPARE(spy2.count(), 1);
- QCOMPARE(spy3.count(), 0);
+ QCOMPARE(spy1.size(), down ? 1 : 0);
+ QCOMPARE(spy2.size(), 1);
+ QCOMPARE(spy3.size(), 0);
QCOMPARE(slider->value(), reportedValue);
QCOMPARE(slider->sliderPosition(), reportedSliderPosition);
if (down)
QVERIFY(sliderMovedTimeStamp < valueChangedTimeStamp);
+
+ slider->setValue(50);
+ QApplication::processEvents();
+ QCOMPARE(spy2.size(), 1);
}
void tst_QAbstractSlider::waitUntilTimeElapsed(const QElapsedTimer &t, int ms)
@@ -2076,37 +2055,37 @@ void tst_QAbstractSlider::setRepeatAction()
// Start repeat action with initial delay of 500 ms, and then repeating
// every 250 ms.
slider->setRepeatAction(QAbstractSlider::SliderPageStepAdd, 500, 250);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
QCOMPARE(slider->value(), 55);
QElapsedTimer t;
t.start();
QTest::qWait(300);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
QCOMPARE(slider->value(), 55);
waitUntilTimeElapsed(t, 550);
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QCOMPARE(slider->value(), 65);
QCOMPARE(spy.at(0).at(0).toUInt(), (uint)QAbstractSlider::SliderPageStepAdd);
waitUntilTimeElapsed(t, 790);
- QTRY_COMPARE(spy.count(), 2);
+ QTRY_COMPARE(spy.size(), 2);
QCOMPARE(slider->value(), 75);
QCOMPARE(spy.at(1).at(0).toUInt(), (uint)QAbstractSlider::SliderPageStepAdd);
waitUntilTimeElapsed(t, 1790);
- QTRY_COMPARE(spy.count(), 6);
+ QTRY_COMPARE(spy.size(), 6);
QCOMPARE(slider->value(), 115);
QCOMPARE(spy.at(4).at(0).toUInt(), (uint)QAbstractSlider::SliderPageStepAdd);
QCOMPARE(spy.at(5).at(0).toUInt(), (uint)QAbstractSlider::SliderPageStepAdd);
slider->setRepeatAction(QAbstractSlider::SliderNoAction);
- QCOMPARE(spy.count(), 6);
+ QCOMPARE(spy.size(), 6);
QCOMPARE(slider->value(), 115);
QTest::qWait(300);
- QCOMPARE(spy.count(), 6);
+ QCOMPARE(spy.size(), 6);
QCOMPARE(slider->value(), 115);
}
diff --git a/tests/auto/widgets/widgets/qabstractspinbox/CMakeLists.txt b/tests/auto/widgets/widgets/qabstractspinbox/CMakeLists.txt
index df077a0bbd..adaef01601 100644
--- a/tests/auto/widgets/widgets/qabstractspinbox/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qabstractspinbox/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qabstractspinbox.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qabstractspinbox Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qabstractspinbox LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qabstractspinbox
SOURCES
tst_qabstractspinbox.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::Gui
Qt::GuiPrivate
diff --git a/tests/auto/widgets/widgets/qabstractspinbox/tst_qabstractspinbox.cpp b/tests/auto/widgets/widgets/qabstractspinbox/tst_qabstractspinbox.cpp
index 6898cf18dc..00d0fdaf94 100644
--- a/tests/auto/widgets/widgets/qabstractspinbox/tst_qabstractspinbox.cpp
+++ b/tests/auto/widgets/widgets/qabstractspinbox/tst_qabstractspinbox.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>
@@ -39,15 +14,12 @@
#include "../../../shared/platforminputcontext.h"
#include <private/qinputmethod_p.h>
+#include <memory>
class tst_QAbstractSpinBox : public QObject
{
Q_OBJECT
-public:
- tst_QAbstractSpinBox();
- virtual ~tst_QAbstractSpinBox();
-
private slots:
void initTestCase();
void cleanupTestCase();
@@ -64,32 +36,25 @@ private:
PlatformInputContext m_platformInputContext;
};
-tst_QAbstractSpinBox::tst_QAbstractSpinBox()
-{
-}
-
-tst_QAbstractSpinBox::~tst_QAbstractSpinBox()
-{
-}
-
class MyAbstractSpinBox : public QAbstractSpinBox
{
public:
- MyAbstractSpinBox() : QAbstractSpinBox() {}
- QLineEdit *lineEdit() { return QAbstractSpinBox::lineEdit(); }
- void setLineEdit(QLineEdit *le) { QAbstractSpinBox::setLineEdit(le); }
+ using QAbstractSpinBox::QAbstractSpinBox;
+
+ using QAbstractSpinBox::lineEdit;
+ using QAbstractSpinBox::setLineEdit;
};
void tst_QAbstractSpinBox::initTestCase()
{
- QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod());
+ auto *inputMethodPrivate = QInputMethodPrivate::get(QGuiApplication::inputMethod());
inputMethodPrivate->testContext = &m_platformInputContext;
}
void tst_QAbstractSpinBox::cleanupTestCase()
{
- QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod());
- inputMethodPrivate->testContext = 0;
+ auto *inputMethodPrivate = QInputMethodPrivate::get(QGuiApplication::inputMethod());
+ inputMethodPrivate->testContext = nullptr;
}
// Testing get/set functions
@@ -112,11 +77,12 @@ void tst_QAbstractSpinBox::getSetCheck()
// QLineEdit * QAbstractSpinBox::lineEdit()
// void QAbstractSpinBox::setLineEdit(QLineEdit *)
- QLineEdit *var3 = new QLineEdit(0);
+ auto *var3 = new QLineEdit(nullptr);
obj1.setLineEdit(var3);
QCOMPARE(var3, obj1.lineEdit());
-#ifndef QT_DEBUG
- obj1.setLineEdit((QLineEdit *)0); // Will assert in debug, so only test in release
+ // Will assert in debug, so only test in release
+#if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS)
+ obj1.setLineEdit(nullptr);
QCOMPARE(var3, obj1.lineEdit()); // Setting 0 should keep the current editor
#endif
// delete var3; // No delete, since QAbstractSpinBox takes ownership
@@ -124,45 +90,38 @@ void tst_QAbstractSpinBox::getSetCheck()
void tst_QAbstractSpinBox::task183108_clear()
{
- QAbstractSpinBox *sbox;
-
- sbox = new QSpinBox;
+ auto sbox = std::make_unique<QSpinBox>();
sbox->clear();
sbox->show();
- qApp->processEvents();
+ QCoreApplication::processEvents();
QVERIFY(sbox->text().isEmpty());
- delete sbox;
- sbox = new QSpinBox;
+ sbox.reset(new QSpinBox);
sbox->clear();
sbox->show();
sbox->hide();
- qApp->processEvents();
+ QCoreApplication::processEvents();
QCOMPARE(sbox->text(), QString());
- delete sbox;
- sbox = new QSpinBox;
+ sbox.reset(new QSpinBox);
sbox->show();
sbox->clear();
- qApp->processEvents();
+ QCoreApplication::processEvents();
QCOMPARE(sbox->text(), QString());
- delete sbox;
- sbox = new QSpinBox;
+ sbox.reset(new QSpinBox);
sbox->show();
sbox->clear();
sbox->hide();
- qApp->processEvents();
+ QCoreApplication::processEvents();
QCOMPARE(sbox->text(), QString());
-
- delete sbox;
}
void tst_QAbstractSpinBox::task228728_cssselector()
{
//QAbstractSpinBox does some call to stylehint into his constructor.
//so while the stylesheet want to access property, it should not crash
- qApp->setStyleSheet("[alignment=\"1\"], [text=\"foo\"] { color:black; }" );
+ qApp->setStyleSheet(R"([alignment="1"], [text="foo"] { color:black; })");
QSpinBox box;
}
@@ -173,24 +132,23 @@ void tst_QAbstractSpinBox::inputMethodUpdate()
QSpinBox box;
- QSpinBox *testWidget = &box;
- testWidget->setRange(0, 1);
+ box.setRange(0, 1);
- QTestPrivate::centerOnScreen(testWidget);
- testWidget->clear();
- testWidget->show();
- QVERIFY(QTest::qWaitForWindowExposed(testWidget));
+ QTestPrivate::centerOnScreen(&box);
+ box.clear();
+ box.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&box));
- testWidget->activateWindow();
- testWidget->setFocus();
- QTRY_VERIFY(testWidget->hasFocus());
- QTRY_COMPARE(qApp->focusObject(), testWidget);
+ box.activateWindow();
+ box.setFocus();
+ QTRY_VERIFY(box.hasFocus());
+ QTRY_COMPARE(QGuiApplication::focusObject(), &box);
m_platformInputContext.m_updateCallCount = 0;
{
QList<QInputMethodEvent::Attribute> attributes;
QInputMethodEvent event("1", attributes);
- QApplication::sendEvent(testWidget, &event);
+ QCoreApplication::sendEvent(&box, &event);
}
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
@@ -199,7 +157,7 @@ void tst_QAbstractSpinBox::inputMethodUpdate()
QList<QInputMethodEvent::Attribute> attributes;
attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 1, QVariant());
QInputMethodEvent event("1", attributes);
- QApplication::sendEvent(testWidget, &event);
+ QCoreApplication::sendEvent(&box, &event);
}
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
@@ -208,17 +166,17 @@ void tst_QAbstractSpinBox::inputMethodUpdate()
QList<QInputMethodEvent::Attribute> attributes;
QInputMethodEvent event("", attributes);
event.setCommitString("1");
- QApplication::sendEvent(testWidget, &event);
+ QCoreApplication::sendEvent(&box, &event);
}
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
- QCOMPARE(testWidget->value(), 1);
+ QCOMPARE(box.value(), 1);
m_platformInputContext.m_updateCallCount = 0;
{
QList<QInputMethodEvent::Attribute> attributes;
attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 0, 0, QVariant());
QInputMethodEvent event("", attributes);
- QApplication::sendEvent(testWidget, &event);
+ QCoreApplication::sendEvent(&box, &event);
}
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
}
diff --git a/tests/auto/widgets/widgets/qbuttongroup/CMakeLists.txt b/tests/auto/widgets/widgets/qbuttongroup/CMakeLists.txt
index 1f876ec5d6..b58775d2ff 100644
--- a/tests/auto/widgets/widgets/qbuttongroup/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qbuttongroup/CMakeLists.txt
@@ -1,13 +1,21 @@
-# Generated from qbuttongroup.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qbuttongroup Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qbuttongroup LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qbuttongroup
SOURCES
tst_qbuttongroup.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
+ Qt::WidgetsPrivate
)
diff --git a/tests/auto/widgets/widgets/qbuttongroup/tst_qbuttongroup.cpp b/tests/auto/widgets/widgets/qbuttongroup/tst_qbuttongroup.cpp
index 8ab2faab43..06d2435601 100644
--- a/tests/auto/widgets/widgets/qbuttongroup/tst_qbuttongroup.cpp
+++ b/tests/auto/widgets/widgets/qbuttongroup/tst_qbuttongroup.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 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) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
@@ -44,6 +19,8 @@
#include <qsettings.h>
#endif
+#include <QtWidgets/private/qapplication_p.h>
+
class SpecialRadioButton: public QRadioButton
{
public:
@@ -145,7 +122,7 @@ void tst_QButtonGroup::arrowKeyNavigation()
layout.addWidget(&g2);
dlg.show();
- qApp->setActiveWindow(&dlg);
+ QApplicationPrivate::setActiveWindow(&dlg);
QVERIFY(QTest::qWaitForWindowActive(&dlg));
bt1.setFocus();
@@ -227,7 +204,7 @@ void tst_QButtonGroup::keyNavigationPushButtons()
buttonGroup->addButton(pb3);
dlg.show();
- qApp->setActiveWindow(&dlg);
+ QApplicationPrivate::setActiveWindow(&dlg);
if (!QTest::qWaitForWindowActive(&dlg))
QSKIP("Window activation failed, skipping test");
@@ -374,17 +351,17 @@ void tst_QButtonGroup::testSignals()
pb1.animateClick();
QTestEventLoop::instance().enterLoop(1);
- QCOMPARE(clickedSpy.count(), 1);
- QCOMPARE(clickedIdSpy.count(), 1);
+ QCOMPARE(clickedSpy.size(), 1);
+ QCOMPARE(clickedIdSpy.size(), 1);
int expectedId = -2;
QCOMPARE(clickedIdSpy.takeFirst().at(0).toInt(), expectedId);
- QCOMPARE(pressedSpy.count(), 1);
- QCOMPARE(pressedIdSpy.count(), 1);
+ QCOMPARE(pressedSpy.size(), 1);
+ QCOMPARE(pressedIdSpy.size(), 1);
QCOMPARE(pressedIdSpy.takeFirst().at(0).toInt(), expectedId);
- QCOMPARE(releasedSpy.count(), 1);
- QCOMPARE(releasedIdSpy.count(), 1);
+ QCOMPARE(releasedSpy.size(), 1);
+ QCOMPARE(releasedIdSpy.size(), 1);
QCOMPARE(releasedIdSpy.takeFirst().at(0).toInt(), expectedId);
clickedSpy.clear();
@@ -397,14 +374,14 @@ void tst_QButtonGroup::testSignals()
pb2.animateClick();
QTestEventLoop::instance().enterLoop(1);
- QCOMPARE(clickedSpy.count(), 1);
- QCOMPARE(clickedIdSpy.count(), 1);
+ QCOMPARE(clickedSpy.size(), 1);
+ QCOMPARE(clickedIdSpy.size(), 1);
QCOMPARE(clickedIdSpy.takeFirst().at(0).toInt(), 23);
- QCOMPARE(pressedSpy.count(), 1);
- QCOMPARE(pressedIdSpy.count(), 1);
+ QCOMPARE(pressedSpy.size(), 1);
+ QCOMPARE(pressedIdSpy.size(), 1);
QCOMPARE(pressedIdSpy.takeFirst().at(0).toInt(), 23);
- QCOMPARE(releasedSpy.count(), 1);
- QCOMPARE(releasedIdSpy.count(), 1);
+ QCOMPARE(releasedSpy.size(), 1);
+ QCOMPARE(releasedIdSpy.size(), 1);
QCOMPARE(releasedIdSpy.takeFirst().at(0).toInt(), 23);
@@ -414,18 +391,18 @@ void tst_QButtonGroup::testSignals()
pb1.setCheckable(true);
pb2.setCheckable(true);
pb1.toggle();
- QCOMPARE(toggledSpy.count(), 1);
- QCOMPARE(toggledIdSpy.count(), 1);
+ QCOMPARE(toggledSpy.size(), 1);
+ QCOMPARE(toggledIdSpy.size(), 1);
pb2.toggle();
- QCOMPARE(toggledSpy.count(), 3); // equals 3 since pb1 and pb2 are both toggled
- QCOMPARE(toggledIdSpy.count(), 3);
+ QCOMPARE(toggledSpy.size(), 3); // equals 3 since pb1 and pb2 are both toggled
+ QCOMPARE(toggledIdSpy.size(), 3);
pb1.setCheckable(false);
pb2.setCheckable(false);
pb1.toggle();
- QCOMPARE(toggledSpy.count(), 3);
- QCOMPARE(toggledIdSpy.count(), 3);
+ QCOMPARE(toggledSpy.size(), 3);
+ QCOMPARE(toggledIdSpy.size(), 3);
}
void tst_QButtonGroup::task106609()
@@ -458,14 +435,14 @@ void tst_QButtonGroup::task106609()
qRegisterMetaType<QAbstractButton*>("QAbstractButton*");
QSignalSpy spy1(buttons, SIGNAL(buttonClicked(QAbstractButton*)));
- QApplication::setActiveWindow(&dlg);
+ QApplicationPrivate::setActiveWindow(&dlg);
QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget*>(&dlg));
radio1->setFocus();
radio1->setChecked(true);
QTestEventLoop::instance().enterLoop(1);
- QCOMPARE(spy1.count(), 2);
+ QCOMPARE(spy1.size(), 2);
}
void tst_QButtonGroup::checkedButton()
@@ -550,7 +527,7 @@ void tst_QButtonGroup::task209485_removeFromGroupInEventHandler()
// NOTE: Reintroducing the bug of this task will cause the following line to crash:
QTest::mouseClick(button, Qt::LeftButton);
- QCOMPARE(spy1.count(), signalCount);
+ QCOMPARE(spy1.size(), signalCount);
}
void tst_QButtonGroup::autoIncrementId()
diff --git a/tests/auto/widgets/widgets/qcalendarwidget/CMakeLists.txt b/tests/auto/widgets/widgets/qcalendarwidget/CMakeLists.txt
index 853ff95a03..5140c37e94 100644
--- a/tests/auto/widgets/widgets/qcalendarwidget/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qcalendarwidget/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qcalendarwidget.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qcalendarwidget Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qcalendarwidget LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qcalendarwidget
SOURCES
tst_qcalendarwidget.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
)
diff --git a/tests/auto/widgets/widgets/qcalendarwidget/tst_qcalendarwidget.cpp b/tests/auto/widgets/widgets/qcalendarwidget/tst_qcalendarwidget.cpp
index 91da5dc69b..ca5cc06e99 100644
--- a/tests/auto/widgets/widgets/qcalendarwidget/tst_qcalendarwidget.cpp
+++ b/tests/auto/widgets/widgets/qcalendarwidget/tst_qcalendarwidget.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>
@@ -109,7 +84,7 @@ void tst_QCalendarWidget::getSetCheck()
QDate selectedDate(2005, 7, 3);
QSignalSpy spy(&object, SIGNAL(selectionChanged()));
object.setSelectedDate(selectedDate);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(selectedDate, object.selectedDate());
//month and year
object.setCurrentPage(2004, 1);
@@ -135,11 +110,19 @@ void tst_QCalendarWidget::getSetCheck()
object.setSelectedDate(selectedDate);
QCOMPARE(minDate, object.selectedDate());
QVERIFY(selectedDate != object.selectedDate());
+ object.clearMinimumDate();
+ object.setSelectedDate(selectedDate);
+ QCOMPARE(selectedDate, object.selectedDate());
+
//date should not go beyond the maximum.
selectedDate = maxDate.addDays(10);
object.setSelectedDate(selectedDate);
QCOMPARE(maxDate, object.selectedDate());
QVERIFY(selectedDate != object.selectedDate());
+ object.clearMaximumDate();
+ object.setSelectedDate(selectedDate);
+ QCOMPARE(selectedDate, object.selectedDate());
+
//show today
QDate today = QDate::currentDate();
object.showToday();
@@ -290,6 +273,9 @@ void tst_QCalendarWidget::showPrevNext()
QFETCH(ShowFunc, function);
QFETCH(QDate, dateOrigin);
QFETCH(QDate, expectedDate);
+#ifdef Q_OS_ANDROID
+ QSKIP("Crashes sometimes on Android emulator, figure out why (QTBUG-102258)");
+#endif
QCalendarWidget calWidget;
calWidget.show();
diff --git a/tests/auto/widgets/widgets/qcheckbox/CMakeLists.txt b/tests/auto/widgets/widgets/qcheckbox/CMakeLists.txt
index df03bea079..9e3f0e9874 100644
--- a/tests/auto/widgets/widgets/qcheckbox/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qcheckbox/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qcheckbox.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qcheckbox Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qcheckbox LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qcheckbox
SOURCES
tst_qcheckbox.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
)
diff --git a/tests/auto/widgets/widgets/qcheckbox/tst_qcheckbox.cpp b/tests/auto/widgets/widgets/qcheckbox/tst_qcheckbox.cpp
index 33fb6b482a..42eb81d3c7 100644
--- a/tests/auto/widgets/widgets/qcheckbox/tst_qcheckbox.cpp
+++ b/tests/auto/widgets/widgets/qcheckbox/tst_qcheckbox.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>
@@ -41,6 +16,7 @@ private slots:
void initTestCase();
void setChecked();
+ void setCheckedSignal();
void setTriState();
void setText_data();
void setText();
@@ -50,7 +26,7 @@ private slots:
void toggle();
void pressed();
void toggled();
- void stateChanged();
+ void checkStateChanged();
void foregroundRole();
void minimumSizeHint();
};
@@ -84,6 +60,25 @@ void tst_QCheckBox::setChecked()
QVERIFY(!testWidget.isChecked());
}
+void tst_QCheckBox::setCheckedSignal()
+{
+ QCheckBox testWidget;
+ testWidget.setCheckState(Qt::Unchecked);
+ QSignalSpy checkStateChangedSpy(&testWidget, &QCheckBox::checkStateChanged);
+ testWidget.setCheckState(Qt::Checked);
+ testWidget.setCheckState(Qt::Checked);
+ QTRY_COMPARE(checkStateChangedSpy.size(), 1); // get signal only once
+ QCOMPARE(testWidget.checkState(), Qt::Checked);
+ testWidget.setCheckState(Qt::Unchecked);
+ testWidget.setCheckState(Qt::Unchecked);
+ QTRY_COMPARE(checkStateChangedSpy.size(), 2); // get signal only once
+ QCOMPARE(testWidget.checkState(), Qt::Unchecked);
+ testWidget.setCheckState(Qt::PartiallyChecked);
+ testWidget.setCheckState(Qt::PartiallyChecked);
+ QTRY_COMPARE(checkStateChangedSpy.size(), 3); // get signal only once
+ QCOMPARE(testWidget.checkState(), Qt::PartiallyChecked);
+}
+
void tst_QCheckBox::setTriState()
{
QCheckBox testWidget;
@@ -213,30 +208,49 @@ void tst_QCheckBox::toggled()
QCOMPARE(click_count, 0);
}
-void tst_QCheckBox::stateChanged()
+void tst_QCheckBox::checkStateChanged()
{
QCheckBox testWidget;
- int cur_state = -1;
+ QCOMPARE(testWidget.checkState(), Qt::Unchecked);
+
+ Qt::CheckState cur_state = Qt::Unchecked;
+ QSignalSpy checkStateChangedSpy(&testWidget, &QCheckBox::checkStateChanged);
+#if QT_DEPRECATED_SINCE(6, 9)
+ QT_IGNORE_DEPRECATIONS(
QSignalSpy stateChangedSpy(&testWidget, &QCheckBox::stateChanged);
- connect(&testWidget, &QCheckBox::stateChanged, this, [&](int state) { ++cur_state = state; });
+ )
+#endif
+ connect(&testWidget, &QCheckBox::checkStateChanged, this, [&](auto state) { cur_state = state; });
testWidget.setChecked(true);
- QCoreApplication::processEvents();
- QCOMPARE(cur_state, 2);
+ QTRY_COMPARE(checkStateChangedSpy.size(), 1);
+#if QT_DEPRECATED_SINCE(6, 9)
+ QCOMPARE(stateChangedSpy.size(), 1);
+#endif
+ QCOMPARE(cur_state, Qt::Checked);
+ QCOMPARE(testWidget.checkState(), Qt::Checked);
- cur_state = -1;
testWidget.setChecked(false);
- QCoreApplication::processEvents();
- QCOMPARE(cur_state, 0);
+ QTRY_COMPARE(checkStateChangedSpy.size(), 2);
+#if QT_DEPRECATED_SINCE(6, 9)
+ QCOMPARE(stateChangedSpy.size(), 2);
+#endif
+ QCOMPARE(cur_state, Qt::Unchecked);
+ QCOMPARE(testWidget.checkState(), Qt::Unchecked);
- cur_state = -1;
testWidget.setCheckState(Qt::PartiallyChecked);
- QCoreApplication::processEvents();
- QCOMPARE(cur_state, 1);
+ QTRY_COMPARE(checkStateChangedSpy.size(), 3);
+#if QT_DEPRECATED_SINCE(6, 9)
+ QCOMPARE(stateChangedSpy.size(), 3);
+#endif
+ QCOMPARE(cur_state, Qt::PartiallyChecked);
+ QCOMPARE(testWidget.checkState(), Qt::PartiallyChecked);
- QCOMPARE(stateChangedSpy.count(), 3);
testWidget.setCheckState(Qt::PartiallyChecked);
QCoreApplication::processEvents();
- QCOMPARE(stateChangedSpy.count(), 3);
+ QCOMPARE(checkStateChangedSpy.size(), 3);
+#if QT_DEPRECATED_SINCE(6, 9)
+ QCOMPARE(stateChangedSpy.size(), 3);
+#endif
}
void tst_QCheckBox::isToggleButton()
diff --git a/tests/auto/widgets/widgets/qcombobox/CMakeLists.txt b/tests/auto/widgets/widgets/qcombobox/CMakeLists.txt
index a1dded1384..87ac247b24 100644
--- a/tests/auto/widgets/widgets/qcombobox/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qcombobox/CMakeLists.txt
@@ -1,9 +1,16 @@
-# Generated from qcombobox.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qcombobox Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qcombobox LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
list(APPEND test_data "qtlogo.png")
list(APPEND test_data "qtlogoinverted.png")
@@ -13,7 +20,7 @@ qt_internal_add_test(tst_qcombobox
tst_qcombobox.cpp
DEFINES
QTEST_QPA_MOUSE_HANDLING
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::Gui
Qt::GuiPrivate
diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
index 4146a6632d..dc6ef789d7 100644
--- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
+++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 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) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
#include <QSignalSpy>
@@ -33,6 +8,7 @@
#include "qcombobox.h"
#include <private/qcombobox_p.h>
#include <private/qguiapplication_p.h>
+#include <qpa/qplatformintegration.h>
#include <qpa/qplatformtheme.h>
#include <qfontcombobox.h>
@@ -49,6 +25,7 @@
#include <qtablewidget.h>
#include <qscrollbar.h>
#include <qboxlayout.h>
+#include <qshortcut.h>
#include <qstackedwidget.h>
#include <qstandarditemmodel.h>
@@ -65,11 +42,15 @@
#include <qstandarditemmodel.h>
#include <qproxystyle.h>
#include <qfont.h>
+#include <qstylehints.h>
#include "../../../shared/platforminputcontext.h"
#include <private/qinputmethod_p.h>
#include <QtTest/private/qtesthelpers_p.h>
+#include <QtTest/private/qemulationdetector_p.h>
+
+#include <QtWidgets/private/qapplication_p.h>
using namespace QTestPrivate;
@@ -130,6 +111,7 @@ private slots:
#ifndef QT_NO_STYLE_FUSION
void task190351_layout();
void task191329_size();
+ void popupPositionAfterStyleChange();
#endif
void task166349_setEditableOnReturn();
void task190205_setModelAdjustToContents();
@@ -170,6 +152,10 @@ private slots:
void checkMenuItemPosWhenStyleSheetIsSet();
void checkEmbeddedLineEditWhenStyleSheetIsSet();
void propagateStyleChanges();
+ void buttonPressKeys();
+ void clearModel();
+ void cancelClosesPopupNotDialog();
+ void closePopupWithCheckableItems();
private:
PlatformInputContext m_platformInputContext;
@@ -472,11 +458,19 @@ void tst_QComboBox::setEditable()
void tst_QComboBox::setPalette()
{
-#ifdef Q_OS_MAC
- if (QApplication::style()->inherits("QMacStyle")) {
- QSKIP("This test doesn't make sense for pixmap-based styles");
- }
-#endif
+ // If (a) Palettes are pixmap based and/or (b) contain color groups/roles which the
+ // resolve mask prevents from being copied, the direct comparison of the inherited
+ // palette and the parent palette will fail.
+ // To prevent that, set a simple gray system palette for QComboBox and QLineEdit
+ const QPalette comboBoxPalette = qApp->palette("QComboBox");
+ const QPalette lineEditPalette = qApp->palette("QLineEdit");
+ auto guard = qScopeGuard([&]{
+ qApp->setPalette(comboBoxPalette, "QComboBox");
+ qApp->setPalette(lineEditPalette, "QLineEdit");
+ });
+ qApp->setPalette(QPalette(Qt::gray), "QComboBox");
+ qApp->setPalette(QPalette(Qt::gray), "QLineEdit");
+
TestWidget topLevel;
topLevel.show();
QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
@@ -484,16 +478,15 @@ void tst_QComboBox::setPalette()
QPalette pal = testWidget->palette();
pal.setColor(QPalette::Base, Qt::red);
testWidget->setPalette(pal);
- testWidget->setEditable(!testWidget->isEditable());
+ testWidget->setEditable(true);
pal.setColor(QPalette::Base, Qt::blue);
testWidget->setPalette(pal);
- const QObjectList comboChildren = testWidget->children();
- for (int i = 0; i < comboChildren.size(); ++i) {
- QObject *o = comboChildren.at(i);
- if (o->isWidgetType()) {
- QCOMPARE(((QWidget*)o)->palette(), pal);
+ const QObjectList &comboChildren = testWidget->children();
+ for (auto *child : comboChildren) {
+ if (auto *widget = qobject_cast<QWidget *>(child)) {
+ QCOMPARE(widget->palette(), pal);
}
}
@@ -770,7 +763,7 @@ void tst_QComboBox::insertPolicy()
testWidget->setInsertPolicy(insertPolicy);
testWidget->addItems(initialEntries);
testWidget->setEditable(true);
- if (initialEntries.count() > 0)
+ if (initialEntries.size() > 0)
testWidget->setCurrentIndex(currentIndex);
// clear
@@ -782,10 +775,10 @@ void tst_QComboBox::insertPolicy()
// First check that there is the right number of entries, or
// we may unwittingly pass
- QCOMPARE((int)result.count(), testWidget->count());
+ QCOMPARE((int)result.size(), testWidget->count());
// No need to compare if there are no strings to compare
- if (result.count() > 0) {
+ if (result.size() > 0) {
for (int i=0; i<testWidget->count(); ++i) {
QCOMPARE(testWidget->itemText(i), result.at(i));
}
@@ -856,7 +849,7 @@ void tst_QComboBox::autoCompletionCaseSensitivity()
TestWidget topLevel;
topLevel.show();
QComboBox *testWidget = topLevel.comboBox();
- qApp->setActiveWindow(&topLevel);
+ QApplicationPrivate::setActiveWindow(&topLevel);
testWidget->setFocus();
QVERIFY(QTest::qWaitForWindowActive(&topLevel));
QCOMPARE(qApp->focusWidget(), (QWidget *)testWidget);
@@ -882,18 +875,18 @@ void tst_QComboBox::autoCompletionCaseSensitivity()
QTest::keyClick(testWidget->lineEdit(), Qt::Key_A);
qApp->processEvents();
QCOMPARE(testWidget->currentText(), QString("aww"));
- QCOMPARE(spyReturn.count(), 0);
+ QCOMPARE(spyReturn.size(), 0);
QTest::keyClick(testWidget->lineEdit(), Qt::Key_B);
qApp->processEvents();
// autocompletions preserve userkey-case from 4.2
QCOMPARE(testWidget->currentText(), QString("abCDEF"));
- QCOMPARE(spyReturn.count(), 0);
+ QCOMPARE(spyReturn.size(), 0);
QTest::keyClick(testWidget->lineEdit(), Qt::Key_Enter);
qApp->processEvents();
QCOMPARE(testWidget->currentText(), QString("aBCDEF")); // case restored to item's case
- QCOMPARE(spyReturn.count(), 1);
+ QCOMPARE(spyReturn.size(), 1);
testWidget->clearEditText();
QTest::keyClick(testWidget->lineEdit(), 'c');
@@ -1029,7 +1022,7 @@ void tst_QComboBox::currentIndex_data()
expectedCurrentIndex = -1;
expectedCurrentText = "";
expectedSignalCount = 2;
- QTest::newRow("check that isetting the index to -1 works")
+ QTest::newRow("check that setting the index to -1 works")
<< initialItems << setCurrentIndex << removeIndex
<< insertIndex << insertText << expectedCurrentIndex << expectedCurrentText
<< expectedSignalCount;
@@ -1172,66 +1165,71 @@ void tst_QComboBox::currentIndex()
TestWidget topLevel;
topLevel.show();
QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
- QComboBox *testWidget = topLevel.comboBox();
+ QComboBox *comboBox = topLevel.comboBox();
// test both editable/non-editable combobox
for (int edit = 0; edit < 2; ++edit) {
- testWidget->clear();
- testWidget->setEditable(edit ? true : false);
+ comboBox->clear();
+ comboBox->setEditable(edit ? true : false);
if (edit)
- QVERIFY(testWidget->lineEdit());
+ QVERIFY(comboBox->lineEdit());
// verify it is empty, has no current index and no current text
- QCOMPARE(testWidget->count(), 0);
- QCOMPARE(testWidget->currentIndex(), -1);
- QVERIFY(testWidget->currentText().isEmpty());
+ QCOMPARE(comboBox->count(), 0);
+ QCOMPARE(comboBox->currentIndex(), -1);
+ QVERIFY(comboBox->currentText().isEmpty());
// spy on currentIndexChanged
- QSignalSpy indexChangedInt(testWidget, SIGNAL(currentIndexChanged(int)));
+ QSignalSpy indexChangedSpy(comboBox, &QComboBox::currentIndexChanged);
// stuff items into it
- foreach(QString text, initialItems) {
- testWidget->addItem(text);
- }
- QCOMPARE(testWidget->count(), initialItems.count());
+ for (const QString &text : initialItems)
+ comboBox->addItem(text);
+
+ QCOMPARE(comboBox->count(), initialItems.size());
// set current index, remove and/or insert
if (setCurrentIndex >= -1) {
- testWidget->setCurrentIndex(setCurrentIndex);
- QCOMPARE(testWidget->currentIndex(), setCurrentIndex);
+ comboBox->setCurrentIndex(setCurrentIndex);
+ QCOMPARE(comboBox->currentIndex(), setCurrentIndex);
}
if (removeIndex >= 0)
- testWidget->removeItem(removeIndex);
+ comboBox->removeItem(removeIndex);
if (insertIndex >= 0)
- testWidget->insertItem(insertIndex, insertText);
+ comboBox->insertItem(insertIndex, insertText);
// compare with expected index and text
- QCOMPARE(testWidget->currentIndex(), expectedCurrentIndex);
- QCOMPARE(testWidget->currentText(), expectedCurrentText);
+ QCOMPARE(comboBox->currentIndex(), expectedCurrentIndex);
+ QCOMPARE(comboBox->currentText(), expectedCurrentText);
// check that signal count is correct
- QCOMPARE(indexChangedInt.count(), expectedSignalCount);
+ QCOMPARE(indexChangedSpy.size(), expectedSignalCount);
// compare with last sent signal values
- if (indexChangedInt.count())
- QCOMPARE(indexChangedInt.at(indexChangedInt.count() - 1).at(0).toInt(),
- testWidget->currentIndex());
+ if (indexChangedSpy.size())
+ QCOMPARE(indexChangedSpy.at(indexChangedSpy.size() - 1).at(0).toInt(),
+ comboBox->currentIndex());
+
+ // Test a no-op index change
+ const int index = comboBox->currentIndex();
+ comboBox->setCurrentIndex(index);
+ QCOMPARE(indexChangedSpy.size(), expectedSignalCount);
if (edit) {
- testWidget->setCurrentIndex(-1);
- testWidget->setInsertPolicy(QComboBox::InsertAtBottom);
- QTest::keyPress(testWidget, 'a');
- QTest::keyPress(testWidget, 'b');
- QCOMPARE(testWidget->currentText(), QString("ab"));
- QCOMPARE(testWidget->currentIndex(), -1);
- int numItems = testWidget->count();
- QTest::keyPress(testWidget, Qt::Key_Return);
- QCOMPARE(testWidget->count(), numItems + 1);
- QCOMPARE(testWidget->currentIndex(), numItems);
- testWidget->setCurrentIndex(-1);
- QTest::keyPress(testWidget, 'a');
- QTest::keyPress(testWidget, 'b');
- QCOMPARE(testWidget->currentIndex(), -1);
+ comboBox->setCurrentIndex(-1);
+ comboBox->setInsertPolicy(QComboBox::InsertAtBottom);
+ QTest::keyPress(comboBox, 'a');
+ QTest::keyPress(comboBox, 'b');
+ QCOMPARE(comboBox->currentText(), QString("ab"));
+ QCOMPARE(comboBox->currentIndex(), -1);
+ int numItems = comboBox->count();
+ QTest::keyPress(comboBox, Qt::Key_Return);
+ QCOMPARE(comboBox->count(), numItems + 1);
+ QCOMPARE(comboBox->currentIndex(), numItems);
+ comboBox->setCurrentIndex(-1);
+ QTest::keyPress(comboBox, 'a');
+ QTest::keyPress(comboBox, 'b');
+ QCOMPARE(comboBox->currentIndex(), -1);
}
}
}
@@ -1251,8 +1249,8 @@ void tst_QComboBox::insertItems_data()
QTest::newRow("prepend") << initialItems << insertedItems << 0 << 0;
QTest::newRow("prepend with negative value") << initialItems << insertedItems << -1 << 0;
- QTest::newRow("append") << initialItems << insertedItems << initialItems.count() << initialItems.count();
- QTest::newRow("append with too high value") << initialItems << insertedItems << 999 << initialItems.count();
+ QTest::newRow("append") << initialItems << insertedItems << initialItems.size() << initialItems.size();
+ QTest::newRow("append with too high value") << initialItems << insertedItems << 999 << initialItems.size();
QTest::newRow("insert") << initialItems << insertedItems << 1 << 1;
}
@@ -1268,12 +1266,12 @@ void tst_QComboBox::insertItems()
QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
QComboBox *testWidget = topLevel.comboBox();
testWidget->insertItems(0, initialItems);
- QCOMPARE(testWidget->count(), initialItems.count());
+ QCOMPARE(testWidget->count(), initialItems.size());
testWidget->insertItems(insertIndex, insertedItems);
- QCOMPARE(testWidget->count(), initialItems.count() + insertedItems.count());
- for (int i=0; i<insertedItems.count(); ++i)
+ QCOMPARE(testWidget->count(), initialItems.size() + insertedItems.size());
+ for (int i=0; i<insertedItems.size(); ++i)
QCOMPARE(testWidget->itemText(expectedIndex + i), insertedItems.at(i));
}
@@ -1289,11 +1287,12 @@ void tst_QComboBox::insertItem_data()
initialItems << "foo" << "bar";
for(int e = 0 ; e<2 ; e++) {
bool editable = (e==0);
- QTest::newRow("Insert less then 0") << initialItems << -1 << "inserted" << 0 << editable;
- QTest::newRow("Insert at 0") << initialItems << 0 << "inserted" << 0 << editable;
- QTest::newRow("Insert beyond count") << initialItems << 3 << "inserted" << 2 << editable;
- QTest::newRow("Insert at count") << initialItems << 2 << "inserted" << 2 << editable;
- QTest::newRow("Insert in the middle") << initialItems << 1 << "inserted" << 1 << editable;
+ const auto txt = editable ? QByteArray("editable: ") : QByteArray("non-editable: ");
+ QTest::newRow(txt + "Insert less then 0") << initialItems << -1 << "inserted" << 0 << editable;
+ QTest::newRow(txt + "Insert at 0") << initialItems << 0 << "inserted" << 0 << editable;
+ QTest::newRow(txt + "Insert beyond count") << initialItems << 3 << "inserted" << 2 << editable;
+ QTest::newRow(txt + "Insert at count") << initialItems << 2 << "inserted" << 2 << editable;
+ QTest::newRow(txt + "Insert in the middle") << initialItems << 1 << "inserted" << 1 << editable;
}
}
@@ -1310,14 +1309,14 @@ void tst_QComboBox::insertItem()
QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
QComboBox *testWidget = topLevel.comboBox();
testWidget->insertItems(0, initialItems);
- QCOMPARE(testWidget->count(), initialItems.count());
+ QCOMPARE(testWidget->count(), initialItems.size());
testWidget->setEditable(true);
if (editable)
testWidget->setEditText("FOO");
testWidget->insertItem(insertIndex, itemLabel);
- QCOMPARE(testWidget->count(), initialItems.count() + 1);
+ QCOMPARE(testWidget->count(), initialItems.size() + 1);
QCOMPARE(testWidget->itemText(expectedIndex), itemLabel);
if (editable)
@@ -1385,21 +1384,21 @@ void tst_QComboBox::textpixmapdata()
QFETCH(IconList, icons);
QFETCH(VariantList, variant);
- QVERIFY(text.count() == icons.count() && text.count() == variant.count());
+ QVERIFY(text.size() == icons.size() && text.size() == variant.size());
TestWidget topLevel;
topLevel.show();
QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
QComboBox *testWidget = topLevel.comboBox();
- for (int i = 0; i<text.count(); ++i) {
+ for (int i = 0; i<text.size(); ++i) {
testWidget->insertItem(i, text.at(i));
testWidget->setItemIcon(i, icons.at(i));
testWidget->setItemData(i, variant.at(i), Qt::UserRole);
}
- QCOMPARE(testWidget->count(), text.count());
+ QCOMPARE(testWidget->count(), text.size());
- for (int i = 0; i<text.count(); ++i) {
+ for (int i = 0; i<text.size(); ++i) {
QIcon icon = testWidget->itemIcon(i);
QCOMPARE(icon.cacheKey(), icons.at(i).cacheKey());
QPixmap original = icons.at(i).pixmap(1024);
@@ -1407,7 +1406,7 @@ void tst_QComboBox::textpixmapdata()
QCOMPARE(pixmap.toImage(), original.toImage());
}
- for (int i = 0; i<text.count(); ++i) {
+ for (int i = 0; i<text.size(); ++i) {
QCOMPARE(testWidget->itemText(i), text.at(i));
// ### we should test icons/pixmap as well, but I need to fix the api mismatch first
QCOMPARE(testWidget->itemData(i, Qt::UserRole), variant.at(i));
@@ -1481,14 +1480,12 @@ void tst_QComboBox::setCurrentText()
else
QCOMPARE(testWidget->currentText(), QString("foo"));
-#ifndef QT_NO_PROPERTIES
// verify WRITE for currentText property
testWidget->setCurrentIndex(0);
const QByteArray n("currentText");
QCOMPARE(testWidget->property(n).toString(), QString("foo"));
testWidget->setProperty(n, QString("bar"));
QCOMPARE(testWidget->property(n).toString(), QString("bar"));
-#endif
}
void tst_QComboBox::currentTextChanged_data()
@@ -1510,42 +1507,70 @@ void tst_QComboBox::currentTextChanged()
testWidget->addItems(QStringList() << "foo" << "bar");
QCOMPARE(testWidget->count(), 2);
- QSignalSpy spy(testWidget, SIGNAL(currentTextChanged(QString)));
+ QSignalSpy textChangedSpy(testWidget, &QComboBox::currentTextChanged);
testWidget->setEditable(editable);
// set text in list
testWidget->setCurrentIndex(0);
QCOMPARE(testWidget->currentIndex(), 0);
- spy.clear();
+ textChangedSpy.clear();
testWidget->setCurrentText(QString("bar"));
- QCOMPARE(spy.count(), 1);
- QCOMPARE(qvariant_cast<QString>(spy.at(0).at(0)), QString("bar"));
+ QCOMPARE(textChangedSpy.size(), 1);
+ QCOMPARE(qvariant_cast<QString>(textChangedSpy.at(0).at(0)), QString("bar"));
// set text not in list
testWidget->setCurrentIndex(0);
QCOMPARE(testWidget->currentIndex(), 0);
- spy.clear();
+ textChangedSpy.clear();
testWidget->setCurrentText(QString("qt"));
if (editable) {
- QCOMPARE(spy.count(), 1);
- QCOMPARE(qvariant_cast<QString>(spy.at(0).at(0)), QString("qt"));
+ QCOMPARE(textChangedSpy.size(), 1);
+ QCOMPARE(qvariant_cast<QString>(textChangedSpy.at(0).at(0)), QString("qt"));
} else {
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(textChangedSpy.size(), 0);
}
// item changed
testWidget->setCurrentIndex(0);
QCOMPARE(testWidget->currentIndex(), 0);
- spy.clear();
+ textChangedSpy.clear();
testWidget->setItemText(0, QString("ape"));
- QCOMPARE(spy.count(), 1);
- QCOMPARE(qvariant_cast<QString>(spy.at(0).at(0)), QString("ape"));
+ QCOMPARE(textChangedSpy.size(), 1);
+ QCOMPARE(qvariant_cast<QString>(textChangedSpy.at(0).at(0)), QString("ape"));
+
// change it back
- spy.clear();
+ textChangedSpy.clear();
testWidget->setItemText(0, QString("foo"));
- QCOMPARE(spy.count(), 1);
- QCOMPARE(qvariant_cast<QString>(spy.at(0).at(0)), QString("foo"));
+ QCOMPARE(textChangedSpy.size(), 1);
+ QCOMPARE(qvariant_cast<QString>(textChangedSpy.at(0).at(0)), QString("foo"));
+
+ // currentIndexChanged vs. currentTextChanged
+ testWidget->clear();
+ testWidget->addItems(QStringList() << "first" << "second" << "third" << "fourth" << "fourth");
+ testWidget->setCurrentIndex(4);
+ textChangedSpy.clear();
+ QSignalSpy indexChangedSpy(testWidget, &QComboBox::currentIndexChanged);
+
+ // Index change w/o text change
+ testWidget->removeItem(3);
+ QCOMPARE(textChangedSpy.count(), 0);
+ QCOMPARE(indexChangedSpy.count(), 1);
+
+ // Index and text change
+ testWidget->setCurrentIndex(0);
+ QCOMPARE(textChangedSpy.count(), 1);
+ QCOMPARE(indexChangedSpy.count(), 2);
+
+ // remove item above current index
+ testWidget->removeItem(2);
+ QCOMPARE(textChangedSpy.count(), 1);
+ QCOMPARE(indexChangedSpy.count(), 2);
+
+ // Text change w/o index change
+ testWidget->setItemText(0, "first class");
+ QCOMPARE(textChangedSpy.count(), 2);
+ QCOMPARE(indexChangedSpy.count(), 2);
}
void tst_QComboBox::editTextChanged()
@@ -1569,13 +1594,13 @@ void tst_QComboBox::editTextChanged()
QCOMPARE(testWidget->currentIndex(), 0);
testWidget->setCurrentIndex(0);
QCOMPARE(testWidget->currentIndex(), 0);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
// no signal should be sent when changing to other index because we are not editable
QCOMPARE(testWidget->currentIndex(), 0);
testWidget->setCurrentIndex(1);
QCOMPARE(testWidget->currentIndex(), 1);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
// now set to editable and reset current index
testWidget->setEditable(true);
@@ -1587,20 +1612,20 @@ void tst_QComboBox::editTextChanged()
QCOMPARE(testWidget->currentIndex(), 0);
testWidget->setCurrentIndex(0);
QCOMPARE(testWidget->currentIndex(), 0);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
// signal should be sent when changing to other index
QCOMPARE(testWidget->currentIndex(), 0);
testWidget->setCurrentIndex(1);
QCOMPARE(testWidget->currentIndex(), 1);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(qvariant_cast<QString>(spy.at(0).at(0)), QString("bar"));
// insert some keys and notice they are all signaled
spy.clear();
QTest::keyClicks(testWidget, "bingo");
- QCOMPARE(spy.count(), 5);
+ QCOMPARE(spy.size(), 5);
QCOMPARE(qvariant_cast<QString>(spy.at(4).at(0)), QString("barbingo"));
}
@@ -1653,6 +1678,16 @@ void tst_QComboBox::setModel()
QCOMPARE(box.rootModelIndex(), rootModelIndex);
box.setModel(box.model());
QCOMPARE(box.rootModelIndex(), rootModelIndex);
+
+ // check that setting the same model as the completer's doesn't crash
+ QCompleter *completer = new QCompleter(&box);
+ box.setEditable(true);
+ box.setCompleter(completer);
+ auto *listModel = new QStringListModel({ "one", "two" }, completer);
+ completer->setModel(listModel);
+ QCOMPARE(listModel->rowCount(), 2); // make sure it wasn't deleted
+ box.setModel(listModel);
+ QCOMPARE(listModel->rowCount(), 2); // make sure it wasn't deleted
}
void tst_QComboBox::setCustomModelAndView()
@@ -1757,7 +1792,7 @@ void tst_QComboBox::setMaxCount()
// insert 5 items at pos 2. Make sure only two get inserted
QSignalSpy spy(box.model(), SIGNAL(rowsInserted(QModelIndex,int,int)));
box.insertItems(2, items);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.at(0).at(1).toInt(), 2);
QCOMPARE(spy.at(0).at(2).toInt(), 3);
@@ -1987,7 +2022,7 @@ void tst_QComboBox::flaggedItems_data()
disableFlagList << 1;
keyMovementList.clear();
keyMovementList << Qt::Key_T << Qt::Key_Enter;
- QTest::newRow(testCase.toLatin1() + "disabled") << itemList << deselectFlagList << disableFlagList << keyMovementList << bool(editable) << 2;
+ QTest::newRow(testCase.toLatin1() + "disabled with key") << itemList << deselectFlagList << disableFlagList << keyMovementList << bool(editable) << 2;
QTest::newRow(testCase.toLatin1() + "broken autocompletion") << itemList << deselectFlagList << disableFlagList << keyMovementList << bool(editable) << 2;
}
}
@@ -1999,8 +2034,8 @@ void tst_QComboBox::flaggedItems()
QSKIP("Wayland: This fails. Figure out why.");
QFETCH(QStringList, itemList);
- QFETCH(IntList, deselectFlagList);
- QFETCH(IntList, disableFlagList);
+ QFETCH(const IntList, deselectFlagList);
+ QFETCH(const IntList, disableFlagList);
QFETCH(KeyList, keyMovementList);
QFETCH(bool, editable);
QFETCH(int, expectedIndex);
@@ -2011,17 +2046,17 @@ void tst_QComboBox::flaggedItems()
listWidget.addItems(itemList);
comboBox.setEditable(editable);
- foreach (int index, deselectFlagList)
+ for (int index : deselectFlagList)
listWidget.item(index)->setFlags(listWidget.item(index)->flags() & ~Qt::ItemIsSelectable);
- foreach (int index, disableFlagList)
+ for (int index : disableFlagList)
listWidget.item(index)->setFlags(listWidget.item(index)->flags() & ~Qt::ItemIsEnabled);
comboBox.setModel(listWidget.model());
comboBox.setView(&listWidget);
comboBox.move(200, 200);
comboBox.show();
- QApplication::setActiveWindow(&comboBox);
+ QApplicationPrivate::setActiveWindow(&comboBox);
comboBox.activateWindow();
comboBox.setFocus();
QVERIFY(QTest::qWaitForWindowActive(&comboBox));
@@ -2031,7 +2066,7 @@ void tst_QComboBox::flaggedItems()
if (editable)
comboBox.lineEdit()->selectAll();
- for (int i = 0; i < keyMovementList.count(); ++i) {
+ for (int i = 0; i < keyMovementList.size(); ++i) {
Qt::Key key = keyMovementList[i];
QTest::keyClick(&comboBox, key);
}
@@ -2097,7 +2132,7 @@ void tst_QComboBox::mouseWheel_data()
void tst_QComboBox::mouseWheel()
{
- QFETCH(IntList, disabledItems);
+ QFETCH(const IntList, disabledItems);
QFETCH(int, startIndex);
QFETCH(int, wheelDirection);
QFETCH(int, expectedIndex);
@@ -2112,7 +2147,7 @@ void tst_QComboBox::mouseWheel()
QListWidget listWidget;
listWidget.addItems(list);
- foreach (int index, disabledItems)
+ for (int index : disabledItems)
listWidget.item(index)->setFlags(listWidget.item(index)->flags() & ~Qt::ItemIsEnabled);
box.setModel(listWidget.model());
@@ -2246,13 +2281,13 @@ void tst_QComboBox::separatorItem_data()
void tst_QComboBox::separatorItem()
{
QFETCH(QStringList, items);
- QFETCH(IntList, separators);
+ QFETCH(const IntList, separators);
QComboBox box;
box.addItems(items);
- foreach(int index, separators)
+ for (int index : separators)
box.insertSeparator(index);
- QCOMPARE(box.count(), (items.count() + separators.count()));
+ QCOMPARE(box.count(), (items.size() + separators.size()));
for (int i = 0, s = 0; i < box.count(); ++i) {
if (i == separators.at(s)) {
QCOMPARE(box.itemText(i), QString());
@@ -2371,7 +2406,8 @@ void tst_QComboBox::task191329_size()
QFrame *container = tableCombo.findChild<QComboBoxPrivateContainer *>();
QVERIFY(container);
QCOMPARE(static_cast<QAbstractItemView *>(table), container->findChild<QAbstractItemView *>());
- foreach (QWidget *button, container->findChildren<QComboBoxPrivateScroller *>()) {
+ const auto buttons = container->findChildren<QComboBoxPrivateScroller *>();
+ for (QWidget *button : buttons) {
//the popup should be large enough to contains everithing so the top and left button are hidden
QVERIFY(!button->isVisible());
}
@@ -2450,7 +2486,7 @@ void tst_QComboBox::task247863_keyBoardSelection()
combo.addItem( QLatin1String("111"));
combo.addItem( QLatin1String("222"));
combo.show();
- QApplication::setActiveWindow(&combo);
+ QApplicationPrivate::setActiveWindow(&combo);
QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&combo));
QSignalSpy spy(&combo, &QComboBox::activated);
@@ -2460,7 +2496,7 @@ void tst_QComboBox::task247863_keyBoardSelection()
QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Down);
QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Enter);
QCOMPARE(combo.currentText(), QLatin1String("222"));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
}
void tst_QComboBox::task220195_keyBoardSelection2()
@@ -2476,7 +2512,7 @@ void tst_QComboBox::task220195_keyBoardSelection2()
combo.addItem( QLatin1String("foo2"));
combo.addItem( QLatin1String("foo3"));
combo.show();
- QApplication::setActiveWindow(&combo);
+ QApplicationPrivate::setActiveWindow(&combo);
QVERIFY(QTest::qWaitForWindowActive(&combo));
combo.setCurrentIndex(-1);
@@ -2735,16 +2771,16 @@ void tst_QComboBox::resetModel()
QComboBox cb;
StringListModel model({"1", "2"});
QSignalSpy spy(&cb, &QComboBox::currentIndexChanged);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
QCOMPARE(cb.currentIndex(), -1); //no selection
cb.setModel(&model);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(cb.currentIndex(), 0); //first item selected
model.reset();
- QCOMPARE(spy.count(), 2);
+ QCOMPARE(spy.size(), 2);
QCOMPARE(cb.currentIndex(), 0); //first item selected
}
@@ -2762,7 +2798,7 @@ void tst_QComboBox::keyBoardNavigationWithMouse()
combo.move(200, 200);
combo.showNormal();
- QApplication::setActiveWindow(&combo);
+ QApplicationPrivate::setActiveWindow(&combo);
QVERIFY(QTest::qWaitForWindowActive(&combo));
QCOMPARE(combo.currentText(), QLatin1String("0"));
@@ -2818,17 +2854,17 @@ void tst_QComboBox::task_QTBUG_1071_changingFocusEmitsActivated()
layout.addWidget(&edit);
w.show();
- QApplication::setActiveWindow(&w);
+ QApplicationPrivate::setActiveWindow(&w);
QVERIFY(QTest::qWaitForWindowActive(&w));
cb.clearEditText();
cb.setFocus();
QApplication::processEvents();
QTRY_VERIFY(cb.hasFocus());
QTest::keyClick(static_cast<QWidget *>(0), '1');
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
edit.setFocus();
QTRY_VERIFY(edit.hasFocus());
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
}
void tst_QComboBox::maxVisibleItems_data()
@@ -3170,31 +3206,55 @@ void tst_QComboBox::task_QTBUG_54191_slotOnEditTextChangedSetsComboBoxToReadOnly
QCOMPARE(cb.currentIndex(), 1);
}
+class ComboBox : public QComboBox {
+public:
+ using QComboBox::QComboBox;
+
+ void keyPressEvent(QKeyEvent *e) override
+ {
+ QComboBox::keyPressEvent(e);
+ accepted = e->isAccepted();
+ }
+ bool accepted = false;
+};
+
void tst_QComboBox::keyboardSelection()
{
- QComboBox comboBox;
+ ComboBox comboBox;
const int keyboardInterval = QApplication::keyboardInputInterval();
- QStringList list;
- list << "OA" << "OB" << "OC" << "OO" << "OP" << "PP";
+ const QStringList list = {"OA", "OB", "OC", "OO", "OP", "PP"};
comboBox.addItems(list);
// Clear any remaining keyboard input from previous tests.
QTest::qWait(keyboardInterval);
QTest::keyClicks(&comboBox, "oo", Qt::NoModifier, 50);
QCOMPARE(comboBox.currentText(), list.at(3));
+ QCOMPARE(comboBox.accepted, true);
QTest::qWait(keyboardInterval);
QTest::keyClicks(&comboBox, "op", Qt::NoModifier, 50);
QCOMPARE(comboBox.currentText(), list.at(4));
+ QCOMPARE(comboBox.accepted, true);
QTest::keyClick(&comboBox, Qt::Key_P, Qt::NoModifier, keyboardInterval);
QCOMPARE(comboBox.currentText(), list.at(5));
+ QCOMPARE(comboBox.accepted, true);
QTest::keyClick(&comboBox, Qt::Key_O, Qt::NoModifier, keyboardInterval);
QCOMPARE(comboBox.currentText(), list.at(0));
+ QCOMPARE(comboBox.accepted, true);
QTest::keyClick(&comboBox, Qt::Key_O, Qt::NoModifier, keyboardInterval);
QCOMPARE(comboBox.currentText(), list.at(1));
+ QCOMPARE(comboBox.accepted, true);
+
+ QTest::keyClick(&comboBox, Qt::Key_Tab, Qt::NoModifier, keyboardInterval);
+ QCOMPARE(comboBox.currentText(), list.at(1));
+ QCOMPARE(comboBox.accepted, false);
+
+ QTest::keyClick(&comboBox, Qt::Key_Tab, Qt::ControlModifier, keyboardInterval);
+ QCOMPARE(comboBox.currentText(), list.at(1));
+ QCOMPARE(comboBox.accepted, false);
}
void tst_QComboBox::updateDelegateOnEditableChange()
@@ -3246,11 +3306,11 @@ void tst_QComboBox::respectChangedOwnershipOfItemView()
QTableView *v2 = new QTableView(&box1);
box1.setView(v2); // Here we do not expect v1 to be deleted
QApplication::processEvents();
- QCOMPARE(spy1.count(), 0);
+ QCOMPARE(spy1.size(), 0);
QSignalSpy spy2(v2, SIGNAL(destroyed()));
box1.setView(v1);
- QCOMPARE(spy2.count(), 1);
+ QCOMPARE(spy2.size(), 1);
}
void tst_QComboBox::task_QTBUG_49831_scrollerNotActivated()
@@ -3271,14 +3331,14 @@ void tst_QComboBox::task_QTBUG_49831_scrollerNotActivated()
QVERIFY(container);
QVERIFY(QTest::qWaitForWindowExposed(container));
- QList<QComboBoxPrivateScroller *> scrollers = container->findChildren<QComboBoxPrivateScroller *>();
+ const QList<QComboBoxPrivateScroller *> scrollers = container->findChildren<QComboBoxPrivateScroller *>();
// Not all styles support scrollers. We rely only on those platforms that do to catch any regression.
if (!scrollers.isEmpty()) {
- Q_FOREACH (QComboBoxPrivateScroller *scroller, scrollers) {
+ for (QComboBoxPrivateScroller *scroller : scrollers) {
if (scroller->isVisible()) {
QSignalSpy doScrollSpy(scroller, SIGNAL(doScroll(int)));
QTest::mouseMove(scroller, QPoint(5, 5), 500);
- QTRY_VERIFY(doScrollSpy.count() > 0);
+ QTRY_VERIFY(doScrollSpy.size() > 0);
}
}
}
@@ -3356,6 +3416,65 @@ void tst_QComboBox::task_QTBUG_56693_itemFontFromModel()
box.hidePopup();
}
+#ifndef QT_NO_STYLE_FUSION
+void tst_QComboBox::popupPositionAfterStyleChange()
+{
+#ifdef Q_OS_QNX
+ QSKIP("Fails on QNX, QTBUG-123798");
+#endif
+ // Check that the popup opens up centered on top of the current
+ // index if the style has changed since the last time it was
+ // opened (QTBUG-113765).
+ QComboBox box;
+ QStyleOptionComboBox opt;
+ const bool usePopup = qApp->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, &box);
+ if (!usePopup)
+ QSKIP("This test is only relevant for styles that centers the popup on top of the combo!");
+ if (QTestPrivate::isRunningArmOnX86())
+ QSKIP("Flaky on QEMU, QTBUG-114760");
+
+ box.addItems({"first", "middle", "last"});
+ box.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&box));
+ box.showPopup();
+
+ QFrame *container = box.findChild<QComboBoxPrivateContainer *>();
+ QVERIFY(container);
+ QVERIFY(QTest::qWaitForWindowExposed(container));
+
+ // Select the last menu item, which will close the popup. This item is then expected
+ // to be centered on top of the combobox the next time the popup opens.
+ const QRect lastItemRect = box.view()->visualRect(box.view()->model()->index(2, 0));
+ QTest::mouseClick(box.view(), Qt::LeftButton, Qt::NoModifier, lastItemRect.center());
+
+ // Change style. This can make the popup smaller, which will result in up-and-down
+ // scroll widgets showing in the menu, directly underneath the mouse before the popup
+ // ends up hidden. This again will trigger the item view to scroll, which seems to be
+ // the root cause of QTBUG-113765.
+ qApp->setStyle(QStringLiteral("Fusion"));
+
+ // Click on the combobox again to reopen it. But since both QComboBox
+ // (QComboBoxPrivateScroller) is using its own internal timer to do scrolling, we
+ // need to wait a bit until the scrolling is done before we can reopen it (since
+ // the scrolling is the sore spot that we want to test).
+ // But note, we expect, but don't require, the popup to scroll. And for that
+ // reason, we don't see it as a failure if the scrolling doesn't happen.
+ (void) QTest::qWaitFor([&box]{ return box.view()->verticalScrollBar()->value() > 0; }, 1000);
+
+ // Verify that the popup is hidden before we click the button
+ QTRY_VERIFY(!container->isVisible());
+ QTest::mouseClick(&box, Qt::LeftButton);
+
+ // Click on item under mouse. But wait a bit, to avoid a double click
+ QTest::qWait(2 * QGuiApplication::styleHints()->mouseDoubleClickInterval());
+ QTest::mouseClick(&box, Qt::LeftButton);
+
+ // Ensure that the item that was centered on top of the combobox, and which
+ // we therefore clicked, was the same item we clicked on the first time.
+ QTRY_COMPARE(box.currentText(), QStringLiteral("last"));
+}
+#endif // QT_NO_STYLE_FUSION
+
void tst_QComboBox::inputMethodUpdate()
{
if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
@@ -3435,10 +3554,10 @@ void tst_QComboBox::task_QTBUG_52027_mapCompleterIndex()
cbox.setCompleter(completer);
QSignalSpy spy(&cbox, SIGNAL(activated(int)));
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
cbox.move(200, 200);
cbox.show();
- QApplication::setActiveWindow(&cbox);
+ QApplicationPrivate::setActiveWindow(&cbox);
QVERIFY(QTest::qWaitForWindowActive(&cbox));
QTest::keyClicks(&cbox, "foobar2");
@@ -3464,7 +3583,7 @@ void tst_QComboBox::task_QTBUG_52027_mapCompleterIndex()
cbox.activateWindow();
}
- QApplication::setActiveWindow(&cbox);
+ QApplicationPrivate::setActiveWindow(&cbox);
QVERIFY(QTest::qWaitForWindowActive(&cbox));
QTest::keyClicks(&cbox, "foobar1");
@@ -3532,7 +3651,7 @@ void tst_QComboBox::checkEmbeddedLineEditWhenStyleSheetIsSet()
layout->addWidget(comboBox);
topLevel.show();
comboBox->setEditable(true);
- QApplication::setActiveWindow(&topLevel);
+ QApplicationPrivate::setActiveWindow(&topLevel);
QVERIFY(QTest::qWaitForWindowActive(&topLevel));
QImage grab = comboBox->grab().toImage();
@@ -3590,5 +3709,144 @@ void tst_QComboBox::propagateStyleChanges()
QVERIFY(frameStyle.inquired);
}
+void tst_QComboBox::buttonPressKeys()
+{
+ QComboBox comboBox;
+ comboBox.setEditable(false);
+ comboBox.addItem(QString::number(1));
+ comboBox.addItem(QString::number(2));
+ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
+ ->themeHint(QPlatformTheme::ButtonPressKeys)
+ .value<QList<Qt::Key>>();
+ for (int i = 0; i < buttonPressKeys.size(); ++i) {
+ QTest::keyClick(&comboBox, buttonPressKeys[i]);
+ // On some platforms, a window will not be immediately visible,
+ // but take some event-loop iterations to complete.
+ // Using QTRY_VERIFY to deal with that.
+ QTRY_VERIFY(comboBox.view()->isVisible());
+ comboBox.hidePopup();
+ }
+}
+
+void tst_QComboBox::clearModel()
+{
+ using namespace Qt::StringLiterals;
+ QStringListModel model({ "one"_L1, "two"_L1, "three"_L1 });
+
+ QComboBox combo;
+ combo.setModel(&model);
+ combo.setCurrentIndex(1);
+
+ QCOMPARE(combo.currentIndex(), 1);
+ QCOMPARE(combo.currentText(), model.index(1).data().toString());
+
+ QSignalSpy indexSpy(&combo, &QComboBox::currentIndexChanged);
+ QSignalSpy textSpy(&combo, &QComboBox::currentTextChanged);
+
+ QVERIFY(indexSpy.isEmpty());
+ QVERIFY(textSpy.isEmpty());
+
+ model.setStringList({});
+
+ QCOMPARE(indexSpy.size(), 1);
+ const int index = indexSpy.takeFirst().at(0).toInt();
+ QCOMPARE(index, -1);
+
+ QCOMPARE(textSpy.size(), 1);
+ const QString text = textSpy.takeFirst().at(0).toString();
+ QCOMPARE(text, QString());
+
+ QCOMPARE(combo.currentIndex(), -1);
+ QCOMPARE(combo.currentText(), QString());
+}
+
+void tst_QComboBox::cancelClosesPopupNotDialog()
+{
+ if (QGuiApplication::platformName() == "offscreen")
+ QSKIP("The offscreen platform plugin doesn't activate popups.");
+
+ if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation))
+ QSKIP("QWindow::requestActivate() is not supported.");
+
+ QDialog dialog;
+ QComboBox combobox;
+ combobox.addItems({"A", "B", "C"});
+
+ std::unique_ptr<QShortcut> shortcut(new QShortcut(QKeySequence::Cancel, &dialog));
+ bool shortcutTriggered = false;
+ connect(shortcut.get(), &QShortcut::activated, [&shortcutTriggered]{
+ shortcutTriggered = true;
+ });
+
+ QVBoxLayout vbox;
+ vbox.addWidget(&combobox);
+ dialog.setLayout(&vbox);
+
+ dialog.show();
+ QVERIFY(QTest::qWaitForWindowActive(&dialog));
+
+ // while the combobox is closed, escape key triggers the shortcut
+ QTest::keyClick(dialog.window()->windowHandle(), Qt::Key_Escape);
+ QVERIFY(shortcutTriggered);
+ shortcutTriggered = false;
+
+ combobox.showPopup();
+ QTRY_VERIFY(combobox.view()->isVisible());
+
+ // an open combobox overrides and accepts the escape key to close
+ QTest::keyClick(dialog.window()->windowHandle(), Qt::Key_Escape);
+ QVERIFY(!shortcutTriggered);
+ shortcutTriggered = false;
+ QTRY_VERIFY(!combobox.view()->isVisible());
+ QVERIFY(dialog.isVisible());
+
+ // once closed, escape key triggers the shortcut again
+ QTest::keyClick(dialog.window()->windowHandle(), Qt::Key_Escape);
+ QVERIFY(shortcutTriggered);
+ shortcutTriggered = false;
+ QVERIFY(dialog.isVisible());
+
+ shortcut.reset();
+
+ // without shortcut, escape key propagates to the parent
+ QTest::keyClick(dialog.window()->windowHandle(), Qt::Key_Escape);
+ QVERIFY(!dialog.isVisible());
+}
+
+void tst_QComboBox::closePopupWithCheckableItems()
+{
+ QWidget widget;
+
+ QVBoxLayout *vb = new QVBoxLayout(&widget);
+
+ QLabel *dlgLabel = new QLabel("Click when combo expanded.");
+ vb->addWidget(dlgLabel);
+
+ QComboBox *combo = new QComboBox();
+ vb->addWidget(combo);
+
+ QStandardItemModel model;
+ const int rowCount = 10;
+ for (int r = 0; r < rowCount; ++r) {
+ QString str = "Item: " + QString::number(r);
+ QStandardItem *item = new QStandardItem(str);
+ const bool isChecked = (r % 2);
+
+ item->setData(isChecked ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
+ item->setFlags(Qt::ItemIsUserCheckable | (item->flags() & ~(Qt::ItemIsSelectable)) );
+ model.appendRow(item);
+ }
+
+ combo->setModel(&model);
+
+ widget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&widget));
+
+ QTest::mouseClick(widget.windowHandle(), Qt::LeftButton, {}, combo->geometry().center());
+ QVERIFY(QTest::qWaitForWindowExposed(combo->view()));
+ QTest::mouseClick(widget.windowHandle(), Qt::LeftButton, {}, dlgLabel->geometry().center());
+ QTRY_VERIFY(!combo->view()->isVisible());
+}
+
QTEST_MAIN(tst_QComboBox)
#include "tst_qcombobox.moc"
diff --git a/tests/auto/widgets/widgets/qcommandlinkbutton/CMakeLists.txt b/tests/auto/widgets/widgets/qcommandlinkbutton/CMakeLists.txt
index dfb555673a..b89c5aa1dd 100644
--- a/tests/auto/widgets/widgets/qcommandlinkbutton/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qcommandlinkbutton/CMakeLists.txt
@@ -1,13 +1,21 @@
-# Generated from qcommandlinkbutton.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qcommandlinkbutton Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qcommandlinkbutton LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qcommandlinkbutton
SOURCES
tst_qcommandlinkbutton.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
+ Qt::GuiPrivate
Qt::Widgets
)
diff --git a/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp b/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp
index 0d9e3a3198..e0c63e5ced 100644
--- a/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp
+++ b/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.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>
@@ -40,6 +15,9 @@
#include <QGridLayout>
#include <QPainter>
+#include <private/qguiapplication_p.h>
+#include <qpa/qplatformtheme.h>
+
class tst_QCommandLinkButton : public QObject
{
Q_OBJECT
@@ -58,7 +36,6 @@ private slots:
void setDown();
void popupCrash();
void isChecked();
- void animateClick();
void toggle();
void clicked();
void toggled();
@@ -227,6 +204,13 @@ void tst_QCommandLinkButton::setAutoRepeat()
// check that pressing ENTER has no effect
resetCounters();
testWidget->setDown( false );
+ // Skip after reset if ButtonPressKeys has Key_Enter
+ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
+ ->themeHint(QPlatformTheme::ButtonPressKeys)
+ .value<QList<Qt::Key>>();
+ if (buttonPressKeys.contains(Qt::Key_Enter)) {
+ return;
+ }
testWidget->setAutoRepeat( false );
QTest::keyPress( testWidget, Qt::Key_Enter );
@@ -259,6 +243,14 @@ void tst_QCommandLinkButton::pressed()
QCOMPARE( press_count, (uint)1 );
QCOMPARE( release_count, (uint)1 );
+ // Skip if ButtonPressKeys has Key_Enter
+ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
+ ->themeHint(QPlatformTheme::ButtonPressKeys)
+ .value<QList<Qt::Key>>();
+ if (buttonPressKeys.contains(Qt::Key_Enter)) {
+ return;
+ }
+
QTest::keyPress( testWidget,Qt::Key_Enter );
QCOMPARE( press_count, (uint)1 );
QCOMPARE( release_count, (uint)1 );
@@ -363,20 +355,6 @@ void tst_QCommandLinkButton::setAccel()
#endif // QT_CONFIG(shortcut)
-void tst_QCommandLinkButton::animateClick()
-{
- QVERIFY( !testWidget->isDown() );
- testWidget->animateClick();
- QVERIFY( testWidget->isDown() );
- QTest::qWait( 200 );
- QVERIFY( !testWidget->isDown() );
-
- QVERIFY( click_count == 1 );
- QVERIFY( press_count == 1 );
- QVERIFY( release_count == 1 );
- QVERIFY( toggle_count == 0 );
-}
-
void tst_QCommandLinkButton::clicked()
{
QTest::mousePress( testWidget, Qt::LeftButton );
diff --git a/tests/auto/widgets/widgets/qdatetimeedit/CMakeLists.txt b/tests/auto/widgets/widgets/qdatetimeedit/CMakeLists.txt
index 8ddb0a3b0d..9c2e777380 100644
--- a/tests/auto/widgets/widgets/qdatetimeedit/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qdatetimeedit/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qdatetimeedit.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qdatetimeedit Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qdatetimeedit LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qdatetimeedit
SOURCES
tst_qdatetimeedit.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::Gui
Qt::Widgets
diff --git a/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp b/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp
index 9211800eb3..f5f22d05b9 100644
--- a/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp
+++ b/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <qapplication.h>
#include <qgroupbox.h>
@@ -72,10 +47,10 @@
#include <private/qdatetimeedit_p.h>
+#include <QtWidgets/private/qapplication_p.h>
+
#ifdef Q_OS_WIN
-# include <windows.h>
-# undef min
-# undef max
+# include <qt_windows.h>
#endif
@@ -258,10 +233,12 @@ private slots:
void nextPrevSection();
void dateEditTimeEditFormats();
+#if QT_DEPRECATED_SINCE(6, 10)
void timeSpec_data();
void timeSpec();
- void timeSpecBug();
- void timeSpecInit();
+#endif
+ void timeZoneBug();
+ void timeZoneInit();
void setDateTime_data();
void setDateTime();
@@ -277,7 +254,7 @@ private slots:
void task196924();
void focusNextPrevChild();
- void taskQTBUG_12384_timeSpecShowTimeOnly();
+ void taskQTBUG_12384_timeZoneShowTimeOnly();
void deleteCalendarWidget();
@@ -431,8 +408,8 @@ void tst_QDateTimeEdit::initTestCase()
qWarning("Running under locale %s/%s -- this test may generate failures due to language differences",
qPrintable(QLocale::languageToString(system.language())),
qPrintable(QLocale::territoryToString(system.territory())));
- testWidget = new EditorDateEdit(0);
- testFocusWidget = new QWidget(0);
+ testWidget = new EditorDateEdit;
+ testFocusWidget = new QWidget(nullptr);
testFocusWidget->resize(200, 100);
testFocusWidget->show();
}
@@ -461,7 +438,7 @@ void tst_QDateTimeEdit::cleanup()
{
testWidget->clearMinimumDateTime();
testWidget->clearMaximumDateTime();
- testWidget->setTimeSpec(Qt::LocalTime);
+ testWidget->setTimeZone(QTimeZone::LocalTime);
testWidget->setSpecialValueText(QString());
testWidget->setWrapping(false);
// Restore the default.
@@ -483,121 +460,104 @@ void tst_QDateTimeEdit::constructor_qwidget()
void tst_QDateTimeEdit::constructor_qdatetime_data()
{
QTest::addColumn<QDateTime>("parameter");
- QTest::addColumn<QDateTime>("displayDateTime");
- QTest::addColumn<QDate>("minimumDate");
- QTest::addColumn<QTime>("minimumTime");
- QTest::addColumn<QDate>("maximumDate");
- QTest::addColumn<QTime>("maximumTime");
-
- QTest::newRow("normal") << QDateTime(QDate(2004, 6, 16), QTime(13, 46, 32, 764))
- << QDateTime(QDate(2004, 6, 16), QTime(13, 46, 32, 764))
- << QDate(1752, 9, 14) << QTime(0, 0, 0, 0)
- << QDate(9999, 12, 31) << QTime(23, 59, 59, 999);
- QTest::newRow("invalid") << QDateTime(QDate(9999, 99, 99), QTime(13, 46, 32, 764))
- << QDateTime(QDate(2000, 1, 1), QTime(0, 0, 0, 0))
- << QDate(1752, 9, 14) << QTime(0, 0, 0, 0)
- << QDate(9999, 12, 31) << QTime(23, 59, 59, 999);
+ QTest::newRow("normal") << QDateTime(QDate(2004, 6, 16), QTime(13, 46, 32, 764));
+ QTest::newRow("invalid") << QDateTime(QDate(9999, 99, 99), QTime(13, 46, 32, 764));
}
void tst_QDateTimeEdit::constructor_qdatetime()
{
QFETCH(QDateTime, parameter);
- QFETCH(QDateTime, displayDateTime);
- QFETCH(QDate, minimumDate);
- QFETCH(QTime, minimumTime);
- QFETCH(QDate, maximumDate);
- QFETCH(QTime, maximumTime);
-
testWidget->hide();
QDateTimeEdit dte(parameter);
dte.show();
- QCOMPARE(dte.dateTime(), displayDateTime);
- QCOMPARE(dte.minimumDate(), minimumDate);
- QCOMPARE(dte.minimumTime(), minimumTime);
- QCOMPARE(dte.maximumDate(), maximumDate);
- QCOMPARE(dte.maximumTime(), maximumTime);
+ if (QByteArrayView(QTest::currentDataTag()) == "invalid")
+ QCOMPARE(dte.dateTime(), QDateTime(QDate(2000, 1, 1), QTime(0, 0)));
+ else
+ QCOMPARE(dte.dateTime(), parameter);
+ QCOMPARE(dte.minimumDate(), QDate(1752, 9, 14));
+ QCOMPARE(dte.minimumTime(), QTime(0, 0));
+ QCOMPARE(dte.maximumDate(), QDate(9999, 12, 31));
+ QCOMPARE(dte.maximumTime(), QTime(23, 59, 59, 999));
}
void tst_QDateTimeEdit::constructor_qdate_data()
{
QTest::addColumn<QDate>("parameter");
- QTest::addColumn<QDateTime>("displayDateTime");
- QTest::addColumn<QDate>("minimumDate");
- QTest::addColumn<QTime>("minimumTime");
- QTest::addColumn<QDate>("maximumDate");
- QTest::addColumn<QTime>("maximumTime");
-
- QTest::newRow("normal") << QDate(2004, 6, 16)
- << QDateTime(QDate(2004, 6, 16), QTime(0, 0, 0, 0))
- << QDate(1752, 9, 14) << QTime(0, 0, 0, 0)
- << QDate(9999, 12, 31) << QTime(23, 59, 59, 999);
- QTest::newRow("invalid") << QDate(9999, 99, 99)
- << QDateTime(QDate(2000, 1, 1), QTime(0, 0, 0, 0))
- << QDate(1752, 9, 14) << QTime(0, 0, 0, 0)
- << QDate(9999, 12, 31) << QTime(23, 59, 59, 999);
+ QTest::newRow("normal") << QDate(2004, 6, 16);
+ QTest::newRow("invalid") << QDate(9999, 99, 99);
}
void tst_QDateTimeEdit::constructor_qdate()
{
QFETCH(QDate, parameter);
- QFETCH(QDateTime, displayDateTime);
- QFETCH(QDate, minimumDate);
- QFETCH(QTime, minimumTime);
- QFETCH(QDate, maximumDate);
- QFETCH(QTime, maximumTime);
-
testWidget->hide();
- QDateTimeEdit dte(parameter);
- dte.show();
- QCOMPARE(dte.dateTime(), displayDateTime);
- QCOMPARE(dte.minimumDate(), minimumDate);
- QCOMPARE(dte.minimumTime(), minimumTime);
- QCOMPARE(dte.maximumDate(), maximumDate);
- QCOMPARE(dte.maximumTime(), maximumTime);
+ {
+ QDateTimeEdit dte(parameter);
+ dte.show();
+ if (QByteArrayView(QTest::currentDataTag()) == "invalid")
+ QCOMPARE(dte.dateTime(), QDateTime(QDate(2000, 1, 1), QTime(0, 0)));
+ else
+ QCOMPARE(dte.dateTime(), QDateTime(parameter, QTime(0, 0)));
+ QCOMPARE(dte.minimumDate(), QDate(1752, 9, 14));
+ QCOMPARE(dte.minimumTime(), QTime(0, 0));
+ QCOMPARE(dte.maximumDate(), QDate(9999, 12, 31));
+ QCOMPARE(dte.maximumTime(), QTime(23, 59, 59, 999));
+ }
+ {
+ QDateEdit dte(parameter);
+ dte.show();
+ if (QByteArrayView(QTest::currentDataTag()) == "invalid")
+ QCOMPARE(dte.date(), QDate(2000, 1, 1));
+ else
+ QCOMPARE(dte.date(), parameter);
+ QCOMPARE(dte.minimumDate(), QDate(1752, 9, 14));
+ QCOMPARE(dte.minimumTime(), QTime(0, 0));
+ QCOMPARE(dte.maximumDate(), QDate(9999, 12, 31));
+ QCOMPARE(dte.maximumTime(), QTime(23, 59, 59, 999));
+ }
}
void tst_QDateTimeEdit::constructor_qtime_data()
{
QTest::addColumn<QTime>("parameter");
- QTest::addColumn<QDateTime>("displayDateTime");
- QTest::addColumn<QDate>("minimumDate");
- QTest::addColumn<QTime>("minimumTime");
- QTest::addColumn<QDate>("maximumDate");
- QTest::addColumn<QTime>("maximumTime");
-
- QTest::newRow("normal") << QTime(13, 46, 32, 764)
- << QDateTime(QDate(2000, 1, 1), QTime(13, 46, 32, 764))
- << QDate(2000, 1, 1) << QTime(0, 0, 0, 0)
- << QDate(2000, 1, 1) << QTime(23, 59, 59, 999);
- QTest::newRow("invalid") << QTime(99, 99, 99, 5000)
- << QDateTime(QDate(2000, 1, 1), QTime(0, 0, 0, 0))
- << QDate(2000, 1, 1) << QTime(0, 0, 0, 0)
- << QDate(2000, 1, 1) << QTime(23, 59, 59, 999);
+ QTest::newRow("normal") << QTime(13, 46, 32, 764);
+ QTest::newRow("invalid") << QTime(99, 99, 99, 5000);
}
void tst_QDateTimeEdit::constructor_qtime()
{
QFETCH(QTime, parameter);
- QFETCH(QDateTime, displayDateTime);
- QFETCH(QDate, minimumDate);
- QFETCH(QTime, minimumTime);
- QFETCH(QDate, maximumDate);
- QFETCH(QTime, maximumTime);
-
testWidget->hide();
- QDateTimeEdit dte(parameter);
- dte.show();
- QCOMPARE(dte.dateTime(), displayDateTime);
- QCOMPARE(dte.minimumDate(), minimumDate);
- QCOMPARE(dte.minimumTime(), minimumTime);
- QCOMPARE(dte.maximumDate(), maximumDate);
- QCOMPARE(dte.maximumTime(), maximumTime);
+ {
+ QDateTimeEdit dte(parameter);
+ dte.show();
+ if (QByteArrayView(QTest::currentDataTag()) == "invalid")
+ QCOMPARE(dte.dateTime(), QDateTime(QDate(2000, 1, 1), QTime(0, 0)));
+ else
+ QCOMPARE(dte.dateTime(), QDateTime(QDate(2000, 1, 1), parameter));
+ QCOMPARE(dte.minimumDate(), QDate(2000, 1, 1));
+ QCOMPARE(dte.minimumTime(), QTime(0, 0));
+ QCOMPARE(dte.maximumDate(), QDate(2000, 1, 1));
+ QCOMPARE(dte.maximumTime(), QTime(23, 59, 59, 999));
+ }
+ {
+ QTimeEdit dte(parameter);
+ dte.show();
+ if (QByteArrayView(QTest::currentDataTag()) == "invalid")
+ QCOMPARE(dte.time(), QTime(0, 0));
+ else
+ QCOMPARE(dte.time(), parameter);
+ QCOMPARE(dte.minimumDate(), QDate(2000, 1, 1));
+ QCOMPARE(dte.minimumTime(), QTime(0, 0));
+ QCOMPARE(dte.maximumDate(), QDate(2000, 1, 1));
+ QCOMPARE(dte.maximumTime(), QTime(23, 59, 59, 999));
+ }
}
void tst_QDateTimeEdit::minimumDate_data()
@@ -867,7 +827,7 @@ void tst_QDateTimeEdit::selectAndScrollWithKeys()
return;
#endif
- qApp->setActiveWindow(testWidget);
+ QApplicationPrivate::setActiveWindow(testWidget);
testWidget->setDate(QDate(2004, 05, 11));
testWidget->setDisplayFormat("dd/MM/yyyy");
testWidget->show();
@@ -969,7 +929,7 @@ void tst_QDateTimeEdit::selectAndScrollWithKeys()
void tst_QDateTimeEdit::backspaceKey()
{
- qApp->setActiveWindow(testWidget);
+ QApplicationPrivate::setActiveWindow(testWidget);
testWidget->setDate(QDate(2004, 05, 11));
testWidget->setDisplayFormat("d/MM/yyyy");
testWidget->show();
@@ -1035,7 +995,7 @@ void tst_QDateTimeEdit::backspaceKey()
void tst_QDateTimeEdit::deleteKey()
{
- qApp->setActiveWindow(testWidget);
+ QApplicationPrivate::setActiveWindow(testWidget);
testWidget->setDate(QDate(2004, 05, 11));
testWidget->setDisplayFormat("d/MM/yyyy");
#ifdef Q_OS_MAC
@@ -1054,7 +1014,7 @@ void tst_QDateTimeEdit::deleteKey()
void tst_QDateTimeEdit::tabKeyNavigation()
{
- qApp->setActiveWindow(testWidget);
+ QApplicationPrivate::setActiveWindow(testWidget);
testWidget->setDate(QDate(2004, 05, 11));
testWidget->setDisplayFormat("dd/MM/yyyy");
testWidget->show();
@@ -1072,7 +1032,7 @@ void tst_QDateTimeEdit::tabKeyNavigation()
void tst_QDateTimeEdit::tabKeyNavigationWithPrefix()
{
- qApp->setActiveWindow(testWidget);
+ QApplicationPrivate::setActiveWindow(testWidget);
testWidget->setDate(QDate(2004, 05, 11));
testWidget->setDisplayFormat("prefix dd/MM/yyyy");
@@ -1090,7 +1050,7 @@ void tst_QDateTimeEdit::tabKeyNavigationWithPrefix()
void tst_QDateTimeEdit::tabKeyNavigationWithSuffix()
{
- qApp->setActiveWindow(testWidget);
+ QApplicationPrivate::setActiveWindow(testWidget);
testWidget->setDate(QDate(2004, 05, 11));
testWidget->setDisplayFormat("dd/MM/yyyy 'suffix'");
@@ -1106,7 +1066,7 @@ void tst_QDateTimeEdit::tabKeyNavigationWithSuffix()
void tst_QDateTimeEdit::enterKey()
{
- qApp->setActiveWindow(testWidget);
+ QApplicationPrivate::setActiveWindow(testWidget);
testWidget->setDate(QDate(2004, 5, 11));
testWidget->setDisplayFormat("prefix d/MM/yyyy 'suffix'");
testWidget->lineEdit()->setFocus();
@@ -1164,7 +1124,7 @@ void tst_QDateTimeEdit::enterKey()
// we include this test so a change to the behaviour can't go unnoticed.
QSignalSpy enterSpy(testWidget, SIGNAL(dateChanged(QDate)));
QTest::keyClick(testWidget, Qt::Key_Enter);
- QCOMPARE(enterSpy.count(), 1);
+ QCOMPARE(enterSpy.size(), 1);
QVariantList list = enterSpy.takeFirst();
QCOMPARE(list.at(0).toDate(), QDate(2004, 5, 9));
}
@@ -1358,7 +1318,7 @@ void tst_QDateTimeEdit::editingRanged_data()
<< QDate(2010, 12, 30) << QTime()
<< QDate(2011, 1, 2) << QTime()
<< QString::fromLatin1("01012011")
- << QDateTime(QDate(2011, 1, 1), QTime(), Qt::UTC);
+ << QDateTime(QDate(2011, 1, 1), QTime(), QTimeZone::UTC);
}
void tst_QDateTimeEdit::editingRanged()
@@ -1394,7 +1354,7 @@ void tst_QDateTimeEdit::editingRanged()
});
edit->show();
- QApplication::setActiveWindow(edit.get());
+ QApplicationPrivate::setActiveWindow(edit.get());
if (!QTest::qWaitForWindowActive(edit.get()))
QSKIP("Failed to make window active, aborting");
edit->setFocus();
@@ -2239,7 +2199,7 @@ void tst_QDateTimeEdit::dateSignalChecking()
QSignalSpy timeSpy(testWidget, SIGNAL(timeChanged(QTime)));
testWidget->setDate(newDate);
- QCOMPARE(dateSpy.count(), timesEmitted);
+ QCOMPARE(dateSpy.size(), timesEmitted);
if (timesEmitted > 0) {
QList<QVariant> list = dateSpy.takeFirst();
@@ -2247,8 +2207,8 @@ void tst_QDateTimeEdit::dateSignalChecking()
d = qvariant_cast<QDate>(list.at(0));
QCOMPARE(d, newDate);
}
- QCOMPARE(dateTimeSpy.count(), timesEmitted);
- QCOMPARE(timeSpy.count(), 0);
+ QCOMPARE(dateTimeSpy.size(), timesEmitted);
+ QCOMPARE(timeSpy.size(), 0);
}
void tst_QDateTimeEdit::timeSignalChecking_data()
@@ -2275,7 +2235,7 @@ void tst_QDateTimeEdit::timeSignalChecking()
QSignalSpy timeSpy(testWidget, SIGNAL(timeChanged(QTime)));
testWidget->setTime(newTime);
- QCOMPARE(timeSpy.count(), timesEmitted);
+ QCOMPARE(timeSpy.size(), timesEmitted);
if (timesEmitted > 0) {
QList<QVariant> list = timeSpy.takeFirst();
@@ -2283,8 +2243,8 @@ void tst_QDateTimeEdit::timeSignalChecking()
t = qvariant_cast<QTime>(list.at(0));
QCOMPARE(t, newTime);
}
- QCOMPARE(dateTimeSpy.count(), timesEmitted);
- QCOMPARE(dateSpy.count(), 0);
+ QCOMPARE(dateTimeSpy.size(), timesEmitted);
+ QCOMPARE(dateSpy.size(), 0);
}
void tst_QDateTimeEdit::dateTimeSignalChecking_data()
@@ -2325,7 +2285,7 @@ void tst_QDateTimeEdit::dateTimeSignalChecking()
QSignalSpy dateTimeSpy(testWidget, SIGNAL(dateTimeChanged(QDateTime)));
testWidget->setDateTime(newDateTime);
- QCOMPARE(dateSpy.count(), timesDateEmitted);
+ QCOMPARE(dateSpy.size(), timesDateEmitted);
if (timesDateEmitted > 0) {
QCOMPARE(timesDateEmitted, 1);
QList<QVariant> list = dateSpy.takeFirst();
@@ -2333,14 +2293,14 @@ void tst_QDateTimeEdit::dateTimeSignalChecking()
d = qvariant_cast<QDate>(list.at(0));
QCOMPARE(d, newDateTime.date());
}
- QCOMPARE(timeSpy.count(), timesTimeEmitted);
+ QCOMPARE(timeSpy.size(), timesTimeEmitted);
if (timesTimeEmitted > 0) {
QList<QVariant> list = timeSpy.takeFirst();
QTime t;
t = qvariant_cast<QTime>(list.at(0));
QCOMPARE(t, newDateTime.time());
}
- QCOMPARE(dateTimeSpy.count(), timesDateTimeEmitted);
+ QCOMPARE(dateTimeSpy.size(), timesDateTimeEmitted);
if (timesDateTimeEmitted > 0) {
QList<QVariant> list = dateTimeSpy.takeFirst();
QDateTime dt;
@@ -3204,22 +3164,22 @@ void tst_QDateTimeEdit::task149097()
testWidget->setDisplayFormat("yyyy/MM/dd hh:mm:ss");
testWidget->setDateTime(QDateTime(QDate(2001, 02, 03), QTime(5, 1, 2)));
// QTest::keyClick(testWidget, Qt::Key_Enter);
- QCOMPARE(dtSpy.count(), 1);
- QCOMPARE(dSpy.count(), 1);
- QCOMPARE(tSpy.count(), 1);
+ QCOMPARE(dtSpy.size(), 1);
+ QCOMPARE(dSpy.size(), 1);
+ QCOMPARE(tSpy.size(), 1);
testWidget->setCurrentSection(QDateTimeEdit::YearSection);
testWidget->stepBy(1);
- QCOMPARE(dtSpy.count(), 2);
- QCOMPARE(dSpy.count(), 2);
- QCOMPARE(tSpy.count(), 1);
+ QCOMPARE(dtSpy.size(), 2);
+ QCOMPARE(dSpy.size(), 2);
+ QCOMPARE(tSpy.size(), 1);
testWidget->setCurrentSection(QDateTimeEdit::MinuteSection);
testWidget->stepBy(1);
- QCOMPARE(dtSpy.count(), 3);
- QCOMPARE(dSpy.count(), 2);
- QCOMPARE(tSpy.count(), 2);
+ QCOMPARE(dtSpy.size(), 3);
+ QCOMPARE(dSpy.size(), 2);
+ QCOMPARE(tSpy.size(), 2);
}
void tst_QDateTimeEdit::task148725()
@@ -3407,7 +3367,7 @@ void tst_QDateTimeEdit::wheelEvent()
QFETCH(QDate, startDate);
QFETCH(DateList, expectedDates);
- EditorDateEdit edit(0);
+ EditorDateEdit edit;
edit.setDate(startDate);
edit.setCurrentSection(section);
@@ -3533,6 +3493,7 @@ void tst_QDateTimeEdit::dateEditTimeEditFormats()
QCOMPARE(d.displayedSections(), QDateTimeEdit::YearSection);
}
+#if QT_DEPRECATED_SINCE(6, 10)
void tst_QDateTimeEdit::timeSpec_data()
{
QTest::addColumn<bool>("useSetProperty");
@@ -3540,6 +3501,8 @@ void tst_QDateTimeEdit::timeSpec_data()
QTest::newRow("setTimeSpec") << false;
}
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
void tst_QDateTimeEdit::timeSpec()
{
QFETCH(bool, useSetProperty);
@@ -3565,7 +3528,7 @@ void tst_QDateTimeEdit::timeSpec()
QCOMPARE(edit.timeSpec(), Qt::LocalTime);
const QDateTime utc = dt.toUTC();
if (dt.time() != utc.time()) {
- const QDateTime min(QDate(1999, 1, 1), QTime(1, 0, 0), Qt::LocalTime);
+ const QDateTime min(QDate(1999, 1, 1), QTime(1, 0));
edit.setMinimumDateTime(min);
QCOMPARE(edit.minimumTime(), min.time());
if (useSetProperty) {
@@ -3580,10 +3543,12 @@ void tst_QDateTimeEdit::timeSpec()
QSKIP("Not tested in the GMT timezone");
}
}
+QT_WARNING_POP
+#endif // test deprecated timeSpec property
-void tst_QDateTimeEdit::timeSpecBug()
+void tst_QDateTimeEdit::timeZoneBug()
{
- testWidget->setTimeSpec(Qt::UTC);
+ testWidget->setTimeZone(QTimeZone::UTC);
testWidget->setDisplayFormat("hh:mm");
testWidget->setTime(QTime(2, 2));
const QString oldText = testWidget->text();
@@ -3593,57 +3558,33 @@ void tst_QDateTimeEdit::timeSpecBug()
QCOMPARE(oldText, testWidget->text());
}
-void tst_QDateTimeEdit::timeSpecInit()
+void tst_QDateTimeEdit::timeZoneInit()
{
- QDateTime utc(QDate(2000, 1, 1), QTime(12, 0, 0), Qt::UTC);
+ QDateTime utc(QDate(2000, 1, 1), QTime(12, 0), QTimeZone::UTC);
QDateTimeEdit widget(utc);
QCOMPARE(widget.dateTime(), utc);
}
void tst_QDateTimeEdit::setDateTime_data()
{
- QTest::addColumn<Qt::TimeSpec>("spec");
- QDateTime localNoon(QDate(2019, 12, 24), QTime(12, 0), Qt::LocalTime);
-#if 0 // Not yet supported
- QTest::addColumn<int>("offset");
- QTest::addColumn<QByteArray>("zoneName");
-
- QTest::newRow("OffsetFromUTC/LocalTime")
- << Qt::OffsetFromUTC << 7200 << ""
- << localNoon << localNoon.toOffsetFromUtc(7200);
-#if QT_CONFIG(timezone)
- QTest::newRow("TimeZone/LocalTime")
- << Qt::TimeZone << 0 << "Europe/Berlin"
- << localNoon << localNoon.toTimeZone(QTimeZone("Europe/Berlin"));
-#endif
-#endif // unsupported
+ const QDateTime localNoon(QDate(2019, 12, 24), QTime(12, 0));
+ const QTimeZone UTC(QTimeZone::UTC), local(QTimeZone::LocalTime);
+ QTest::addColumn<QTimeZone>("zone");
QTest::addColumn<QDateTime>("store");
QTest::addColumn<QDateTime>("expect");
- QTest::newRow("LocalTime/LocalTime")
- << Qt::LocalTime // << 0 << ""
- << localNoon << localNoon;
- QTest::newRow("LocalTime/UTC")
- << Qt::LocalTime // << 0 << ""
- << localNoon.toUTC() << localNoon;
- QTest::newRow("UTC/LocalTime")
- << Qt::UTC // << 0 << ""
- << localNoon << localNoon.toUTC();
- QTest::newRow("UTC/UTC")
- << Qt::UTC // << 0 << ""
- << localNoon.toUTC() << localNoon.toUTC();
+ QTest::newRow("LocalTime/LocalTime") << local << localNoon << localNoon;
+ QTest::newRow("LocalTime/UTC") << local << localNoon.toUTC() << localNoon;
+ QTest::newRow("UTC/LocalTime") << UTC << localNoon << localNoon.toUTC();
+ QTest::newRow("UTC/UTC") << UTC << localNoon.toUTC() << localNoon.toUTC();
}
void tst_QDateTimeEdit::setDateTime()
{
- QFETCH(const Qt::TimeSpec, spec);
-#if 0 // Not yet supported
- QFETCH(const int, offset);
- QFETCH(const QByteArray, zoneName);
-#endif // configuring the spec, when OffsetFromUTC or TimeZone
+ QFETCH(const QTimeZone, zone);
QFETCH(const QDateTime, store);
QFETCH(const QDateTime, expect);
QDateTimeEdit editor;
- editor.setTimeSpec(spec);
+ editor.setTimeZone(zone);
editor.setDateTime(store);
QCOMPARE(editor.dateTime(), expect);
}
@@ -3837,14 +3778,14 @@ void tst_QDateTimeEdit::focusNextPrevChild()
QCOMPARE(edit.currentSection(), QDateTimeEdit::MonthSection);
}
-void tst_QDateTimeEdit::taskQTBUG_12384_timeSpecShowTimeOnly()
+void tst_QDateTimeEdit::taskQTBUG_12384_timeZoneShowTimeOnly()
{
QDateTime time = QDateTime::fromString("20100723 04:02:40", "yyyyMMdd hh:mm:ss");
- time.setTimeSpec(Qt::UTC);
+ time.setTimeZone(QTimeZone::UTC);
EditorDateEdit edit;
edit.setDisplayFormat("hh:mm:ss");
- edit.setTimeSpec(Qt::UTC);
+ edit.setTimeZone(QTimeZone::UTC);
edit.setDateTime(time);
QCOMPARE(edit.minimumTime(), QTime(0, 0, 0, 0));
@@ -3860,7 +3801,7 @@ void tst_QDateTimeEdit::deleteCalendarWidget()
QVERIFY(!edit.calendarWidget());
edit.setCalendarPopup(true);
QVERIFY(edit.calendarWidget());
- edit.calendarWidget()->setObjectName("cw1");;
+ edit.calendarWidget()->setObjectName("cw1");
// delete
delete edit.calendarWidget();
@@ -4486,7 +4427,7 @@ void tst_QDateTimeEdit::stepModifierButtons()
testWidget->hide();
- EditorDateEdit edit(0);
+ EditorDateEdit edit;
edit.setTime(startTime);
edit.show();
QVERIFY(QTest::qWaitForWindowActive(&edit));
@@ -4572,11 +4513,15 @@ void tst_QDateTimeEdit::stepModifierPressAndHold()
QFETCH(Qt::KeyboardModifiers, modifiers);
QFETCH(int, expectedStepModifier);
- const QDate startDate(2000, 1, 1);
+ // Some west African zones (e.g. Niamey, Conakry) changed from 1 hour west
+ // of GMT to GMT at the start of 1960; and spy.size() can get as high as 4,
+ // causing the expectedDate below, when expectedStepModifier is -10, to land
+ // in a transition gap for these zones, if we use Jan 1st; so use Jan 2nd.
+ const QDate startDate(2000, 1, 2);
testWidget->hide();
- EditorDateEdit edit(0);
+ EditorDateEdit edit;
edit.setDate(startDate);
QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> stepModifierStyle(
@@ -4597,12 +4542,12 @@ void tst_QDateTimeEdit::stepModifierPressAndHold()
QStyle::CC_SpinBox, &spinBoxStyleOption, subControl, &edit);
QTest::mousePress(&edit, Qt::LeftButton, modifiers, buttonRect.center());
- QTRY_VERIFY(spy.length() >= 3);
+ QTRY_VERIFY(spy.size() >= 3);
QTest::mouseRelease(&edit, Qt::LeftButton, modifiers, buttonRect.center());
const auto value = spy.last().at(0);
QVERIFY(value.userType() == QMetaType::QDate);
- const QDate expectedDate = startDate.addYears(spy.length() *
+ const QDate expectedDate = startDate.addYears(spy.size() *
expectedStepModifier);
QCOMPARE(value.toDate(), expectedDate);
}
@@ -4626,13 +4571,20 @@ static QDateTime findSpring(int year, const QTimeZone &timeZone)
const QTimeZone::OffsetData transition =
midSummer.isDaylightTime() ? timeZone.previousTransition(midSummer)
: timeZone.nextTransition(midSummer);
- const QDateTime spring = transition.atUtc.toLocalTime();
+ const QDateTime spring = transition.atUtc.toTimeZone(timeZone);
// there might have been DST at some point, but not in the year we care about
if (spring.date().year() != year || !spring.isDaylightTime())
return QDateTime();
return spring;
};
+
+// Number of missing seconds between a day before and a day after when.
+// If when is the time of a spring-forward transition, this is the width of its gap.
+static int missingSecondsNear(const QDateTime &when)
+{
+ return 2 * 24 * 60 * 60 - when.addDays(-1).secsTo(when.addDays(1));
+}
#endif
/*!
@@ -4656,36 +4608,40 @@ void tst_QDateTimeEdit::springForward_data()
QSKIP("Failed to obtain valid spring forward datetime for 2019!");
const QDate springDate = springTransition.date();
- const int gapWidth = timeZone.daylightTimeOffset(springTransition.addDays(1));
+ const int gapWidth = missingSecondsNear(springTransition);
+ if (gapWidth <= 0)
+ QSKIP("Spring forward transition did not actually skip any time!");
+
const QTime springGap = springTransition.time().addSecs(-gapWidth);
- const QByteArray springTime = springGap.toString("hh:mm").toLocal8Bit();
- const QTime springGapMiddle = springTransition.time().addSecs(-gapWidth/2);
+ const QTime springGapMiddle = springTransition.time().addSecs(-gapWidth / 2);
+ const QByteArray startGapTime = springGap.toString("hh:mm").toLocal8Bit();
+ const QByteArray midGapTime = springGapMiddle.toString("hh:mm").toLocal8Bit();
- QTest::addRow("forward to %s, correct to previous", springTime.data())
+ QTest::addRow("forward to %s, correct to previous", startGapTime.data())
<< QDateTime(springDate, springGap.addSecs(-gapWidth))
<< QAbstractSpinBox::CorrectToPreviousValue
<< springGap
<< QDateTime(springDate, springGap.addSecs(-gapWidth));
- QTest::addRow("back to %s, correct to previous", springTime.data())
+ QTest::addRow("back to %s, correct to previous", startGapTime.data())
<< springTransition
<< QAbstractSpinBox::CorrectToPreviousValue
<< springGap
<< springTransition;
- QTest::addRow("forward to %s, correct to nearest", springTime.data())
+ QTest::addRow("forward to %s, correct to nearest", midGapTime.data())
<< QDateTime(springDate, springGap.addSecs(-gapWidth))
<< QAbstractSpinBox::CorrectToNearestValue
<< springGapMiddle
<< springTransition;
- QTest::addRow("back to %s, correct to nearest", springTime.data())
+ QTest::addRow("back to %s, correct to nearest", midGapTime.data())
<< springTransition
<< QAbstractSpinBox::CorrectToNearestValue
<< springGapMiddle
<< springTransition;
- QTest::addRow("jump to %s, correct to nearest", qPrintable(springGapMiddle.toString("hh:mm")))
+ QTest::addRow("jump to %s, correct to nearest", midGapTime.data())
<< QDateTime(QDate(1980, 5, 10), springGap)
<< QAbstractSpinBox::CorrectToNearestValue
<< springGapMiddle
@@ -4713,11 +4669,11 @@ void tst_QDateTimeEdit::springForward()
edit.setSelectedSection(QDateTimeEdit::DaySection);
const QDate date = expected.date();
- const QString day = QString::number(date.day()).rightJustified(2, QLatin1Char('0'));
- const QString month = QString::number(date.month()).rightJustified(2, QLatin1Char('0'));
+ const QString day = QString::number(date.day()).rightJustified(2, u'0');
+ const QString month = QString::number(date.month()).rightJustified(2, u'0');
const QString year = QString::number(date.year());
- const QString hour = QString::number(inputTime.hour()).rightJustified(2, QLatin1Char('0'));
- const QString minute = QString::number(inputTime.minute()).rightJustified(2, QLatin1Char('0'));
+ const QString hour = QString::number(inputTime.hour()).rightJustified(2, u'0');
+ const QString minute = QString::number(inputTime.minute()).rightJustified(2, u'0');
QTest::keyClicks(&edit, day);
QTest::keyClicks(&edit, month);
QTest::keyClicks(&edit, year);
@@ -4744,7 +4700,7 @@ void tst_QDateTimeEdit::stepIntoDSTGap_data()
QTest::addColumn<int>("steps");
QTest::addColumn<QDateTime>("end");
- const QTimeZone timeZone = QTimeZone("Europe/Oslo");
+ const QTimeZone timeZone = QTimeZone::systemTimeZone();
if (!timeZone.hasDaylightTime())
QSKIP("This test needs to run in a timezone that observes DST!");
@@ -4753,11 +4709,14 @@ void tst_QDateTimeEdit::stepIntoDSTGap_data()
QSKIP("Failed to obtain valid spring forward datetime for 2007!");
const QDate spring = springTransition.date();
- const int gapWidth = timeZone.daylightTimeOffset(springTransition.addDays(1));
+ const int gapWidth = missingSecondsNear(springTransition);
+ if (gapWidth <= 0)
+ QSKIP("Spring forward transition did not actually skip any time!");
+
const QTime springGap = springTransition.time().addSecs(-gapWidth);
const QByteArray springTime = springGap.toString("hh:mm").toLocal8Bit();
- // change hour
+ // change hour (can't change day):
if (springGap.hour() != 0) {
QTest::addRow("hour up into %s gap", springTime.data())
<< QDateTime(spring, springGap.addSecs(-3600))
@@ -4767,7 +4726,7 @@ void tst_QDateTimeEdit::stepIntoDSTGap_data()
// 3:00:10 into 2:00:10 should get us to 1:00:10
QTest::addRow("hour down into %s gap", springTime.data())
- << QDateTime(spring, springGap.addSecs(3610))
+ << QDateTime(spring, springGap.addSecs(gapWidth + 10))
<< QDateTimeEdit::HourSection
<< -1
<< QDateTime(spring, springGap.addSecs(-3590));
@@ -4792,28 +4751,31 @@ void tst_QDateTimeEdit::stepIntoDSTGap_data()
}
// change month
- QTest::addRow("month up into %s gap", springTime.data())
- << QDateTime(spring.addMonths(-1), springGap)
- << QDateTimeEdit::MonthSection
- << +1
- << springTransition;
- QTest::addRow("month down into %s gap", springTime.data())
- << QDateTime(spring.addMonths(1), springGap)
- << QDateTimeEdit::MonthSection
- << -1
- << springTransition;
+ // Previous month may well be February, so lack the day-of-month that
+ // matches spring (e.g. Asia/Jerusalem, March 30).
+ if (QDate prior = spring.addMonths(-1); prior.day() == spring.day()) {
+ QTest::addRow("month up into %s gap", springTime.data())
+ << QDateTime(prior, springGap) << QDateTimeEdit::MonthSection << +1 << springTransition;
+ }
+ // America/{Jujuy,Cordoba,Catamarca} did a 2007 Dec 30th 00:00 spring
+ // forward; and QDTE month steps won't change the year.
+ if (QDate prior = spring.addMonths(1);
+ prior.year() == spring.year() && prior.day() == spring.day()) {
+ QTest::addRow("month down into %s gap", springTime.data())
+ << QDateTime(prior, springGap) << QDateTimeEdit::MonthSection << -1 << springTransition;
+ }
// change year
- QTest::addRow("year up into %s gap", springTime.data())
- << QDateTime(spring.addYears(-1), springGap)
- << QDateTimeEdit::YearSection
- << +1
- << springTransition;
- QTest::addRow("year down into %s gap", springTime.data())
- << QDateTime(spring.addYears(1), springGap)
- << QDateTimeEdit::YearSection
- << -1
- << springTransition;
+ // Some zones (e.g. Asia/Baghdad) do transitions on a fixed date; for these,
+ // the springGap moment is invalid every year, so skip this test.
+ if (QDateTime prior = QDateTime(spring.addYears(-1), springGap); prior.isValid()) {
+ QTest::addRow("year up into %s gap", springTime.data())
+ << prior << QDateTimeEdit::YearSection << +1 << springTransition;
+ }
+ if (QDateTime later(spring.addYears(1), springGap); later.isValid()) {
+ QTest::addRow("year down into %s gap", springTime.data())
+ << later << QDateTimeEdit::YearSection << -1 << springTransition;
+ }
#else
QSKIP("Needs timezone feature enabled");
#endif
diff --git a/tests/auto/widgets/widgets/qdial/CMakeLists.txt b/tests/auto/widgets/widgets/qdial/CMakeLists.txt
index e76cc4a7db..5e300eec94 100644
--- a/tests/auto/widgets/widgets/qdial/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qdial/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qdial.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qdial Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qdial LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qdial
SOURCES
tst_qdial.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
)
diff --git a/tests/auto/widgets/widgets/qdial/tst_qdial.cpp b/tests/auto/widgets/widgets/qdial/tst_qdial.cpp
index 86928414c8..d0274ace2a 100644
--- a/tests/auto/widgets/widgets/qdial/tst_qdial.cpp
+++ b/tests/auto/widgets/widgets/qdial/tst_qdial.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>
@@ -42,6 +17,7 @@ private slots:
void valueChanged();
void sliderMoved();
void wrappingCheck();
+ void minEqualMaxValueOutsideRange();
void notchSize_data();
void notchSize();
@@ -77,14 +53,14 @@ void tst_QDial::valueChanged()
dial.setMaximum(100);
QSignalSpy spy(&dial, SIGNAL(valueChanged(int)));
dial.setValue(50);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
dial.setValue(25);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
// repeat!
dial.setValue(25);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
}
void tst_QDial::sliderMoved()
@@ -100,7 +76,7 @@ void tst_QDial::sliderMoved()
QPoint init(dial.width()/4, dial.height()/2);
- QMouseEvent pressevent(QEvent::MouseButtonPress, init,
+ QMouseEvent pressevent(QEvent::MouseButtonPress, init, dial.mapToGlobal(init),
Qt::LeftButton, Qt::LeftButton, {});
qApp->sendEvent(&dial, &pressevent);
@@ -110,27 +86,27 @@ void tst_QDial::sliderMoved()
{ //move on top of the slider
init = QPoint(dial.width()/2, dial.height()/4);
- QMouseEvent moveevent(QEvent::MouseMove, init,
+ QMouseEvent moveevent(QEvent::MouseMove, init, dial.mapToGlobal(init),
Qt::LeftButton, Qt::LeftButton, {});
qApp->sendEvent(&dial, &moveevent);
- QCOMPARE( sliderspy.count(), 1);
- QCOMPARE( valuespy.count(), 0);
+ QCOMPARE( sliderspy.size(), 1);
+ QCOMPARE( valuespy.size(), 0);
}
{ //move on the right of the slider
init = QPoint(dial.width()*3/4, dial.height()/2);
- QMouseEvent moveevent(QEvent::MouseMove, init,
+ QMouseEvent moveevent(QEvent::MouseMove, init, dial.mapToGlobal(init),
Qt::LeftButton, Qt::LeftButton, {});
qApp->sendEvent(&dial, &moveevent);
- QCOMPARE( sliderspy.count(), 2);
- QCOMPARE( valuespy.count(), 0);
+ QCOMPARE( sliderspy.size(), 2);
+ QCOMPARE( valuespy.size(), 0);
}
- QMouseEvent releaseevent(QEvent::MouseButtonRelease, init,
+ QMouseEvent releaseevent(QEvent::MouseButtonRelease, init, dial.mapToGlobal(init),
Qt::LeftButton, Qt::LeftButton, {});
qApp->sendEvent(&dial, &releaseevent);
- QCOMPARE( valuespy.count(), 1); // valuechanged signal should be called at this point
+ QCOMPARE( valuespy.size(), 1); // valuechanged signal should be called at this point
}
@@ -197,6 +173,15 @@ void tst_QDial::wrappingCheck()
}
}
+// QTBUG-104641
+void tst_QDial::minEqualMaxValueOutsideRange()
+{
+ QDial dial;
+ dial.setRange(30, 30);
+ dial.setWrapping(true);
+ dial.setValue(45);
+}
+
/*
Verify that the notchSizes calculated don't change compared
to Qt 5.15 results for dial sizes at the edge values of the
diff --git a/tests/auto/widgets/widgets/qdialogbuttonbox/CMakeLists.txt b/tests/auto/widgets/widgets/qdialogbuttonbox/CMakeLists.txt
index c42fccd87f..098b129cbc 100644
--- a/tests/auto/widgets/widgets/qdialogbuttonbox/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qdialogbuttonbox/CMakeLists.txt
@@ -1,13 +1,21 @@
-# Generated from qdialogbuttonbox.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qdialogbuttonbox Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qdialogbuttonbox LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qdialogbuttonbox
SOURCES
tst_qdialogbuttonbox.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
+ Qt::WidgetsPrivate
)
diff --git a/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp b/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp
index 2e7e248db7..3e7dc92da1 100644
--- a/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp
+++ b/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp
@@ -1,38 +1,17 @@
-/****************************************************************************
-**
-** 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>
#include <QSignalSpy>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QStyle>
#include <QtWidgets/QLayout>
#include <QtWidgets/QDialog>
+#include <QtWidgets/QLineEdit>
#include <QtGui/QAction>
+#include <QtGui/QStyleHints>
#include <qdialogbuttonbox.h>
+#include <QtWidgets/private/qdialogbuttonbox_p.h>
+#include <QtWidgets/private/qabstractbutton_p.h>
#include <limits.h>
Q_DECLARE_METATYPE(QDialogButtonBox::ButtonRole)
@@ -74,6 +53,10 @@ private slots:
void clear();
void removeButton_data();
void removeButton();
+#ifdef QT_BUILD_INTERNAL
+ void hideAndShowButton();
+#endif
+ void hideAndShowStandardButton();
void buttonRole_data();
void buttonRole();
void setStandardButtons_data();
@@ -99,6 +82,9 @@ private slots:
void task191642_default();
void testDeletedStandardButton();
+ void automaticDefaultButton();
+ void initialFocus_data();
+ void initialFocus();
private:
qint64 timeStamp;
@@ -122,7 +108,7 @@ void tst_QDialogButtonBox::testConstructor1()
QDialogButtonBox buttonbox;
QCOMPARE(buttonbox.orientation(), Qt::Horizontal);
- QCOMPARE(buttonbox.buttons().count(), 0);
+ QCOMPARE(buttonbox.buttons().size(), 0);
}
void tst_QDialogButtonBox::layoutReuse()
@@ -155,7 +141,7 @@ void tst_QDialogButtonBox::testConstructor2()
QDialogButtonBox buttonBox(orient);
QCOMPARE(buttonBox.orientation(), orient);
- QCOMPARE(buttonBox.buttons().count(), 0);
+ QCOMPARE(buttonBox.buttons().size(), 0);
}
void tst_QDialogButtonBox::testConstructor3_data()
@@ -192,7 +178,7 @@ void tst_QDialogButtonBox::testConstructor3()
QDialogButtonBox buttonBox(buttons, (Qt::Orientation)orientation);
QCOMPARE(int(buttonBox.orientation()), orientation);
- QTEST(int(buttonBox.buttons().count()), "buttonCount");
+ QTEST(int(buttonBox.buttons().size()), "buttonCount");
}
void tst_QDialogButtonBox::testConstructor4_data()
@@ -227,7 +213,7 @@ void tst_QDialogButtonBox::testConstructor4()
QDialogButtonBox buttonBox(buttons);
QCOMPARE(buttonBox.orientation(), Qt::Horizontal);
- QTEST(int(buttonBox.buttons().count()), "buttonCount");
+ QTEST(int(buttonBox.buttons().size()), "buttonCount");
}
void tst_QDialogButtonBox::setOrientation_data()
@@ -290,12 +276,12 @@ void tst_QDialogButtonBox::addButton1()
{
QFETCH(QDialogButtonBox::ButtonRole, role);
QDialogButtonBox buttonBox;
- QCOMPARE(buttonBox.buttons().count(), 0);
+ QCOMPARE(buttonBox.buttons().size(), 0);
QPushButton *button = new QPushButton();
buttonBox.addButton(button, role);
- QTEST(int(buttonBox.buttons().count()), "totalCount");
+ QTEST(int(buttonBox.buttons().size()), "totalCount");
QList<QAbstractButton *> children = buttonBox.findChildren<QAbstractButton *>();
- QTEST(int(children.count()), "totalCount");
+ QTEST(int(children.size()), "totalCount");
delete button;
}
@@ -318,11 +304,11 @@ void tst_QDialogButtonBox::addButton2()
QFETCH(QString, text);
QFETCH(QDialogButtonBox::ButtonRole, role);
QDialogButtonBox buttonBox;
- QCOMPARE(buttonBox.buttons().count(), 0);
+ QCOMPARE(buttonBox.buttons().size(), 0);
buttonBox.addButton(text, role);
- QTEST(int(buttonBox.buttons().count()), "totalCount");
+ QTEST(int(buttonBox.buttons().size()), "totalCount");
QList<QAbstractButton *> children = buttonBox.findChildren<QAbstractButton *>();
- QTEST(int(children.count()), "totalCount");
+ QTEST(int(children.size()), "totalCount");
}
void tst_QDialogButtonBox::addButton3_data()
@@ -345,11 +331,11 @@ void tst_QDialogButtonBox::addButton3()
{
QFETCH(QDialogButtonBox::StandardButton, button);
QDialogButtonBox buttonBox;
- QCOMPARE(buttonBox.buttons().count(), 0);
+ QCOMPARE(buttonBox.buttons().size(), 0);
buttonBox.addButton(button);
- QTEST(int(buttonBox.buttons().count()), "totalCount");
+ QTEST(int(buttonBox.buttons().size()), "totalCount");
QList<QAbstractButton *> children = buttonBox.findChildren<QAbstractButton *>();
- QTEST(int(children.count()), "totalCount");
+ QTEST(int(children.size()), "totalCount");
}
void tst_QDialogButtonBox::clear_data()
@@ -369,9 +355,9 @@ void tst_QDialogButtonBox::clear()
for (int i = 1; i < rolesToAdd; ++i)
buttonBox.addButton("Happy", QDialogButtonBox::ButtonRole(i));
buttonBox.clear();
- QCOMPARE(buttonBox.buttons().count(), 0);
+ QCOMPARE(buttonBox.buttons().size(), 0);
QList<QAbstractButton *> children = buttonBox.findChildren<QAbstractButton *>();
- QCOMPARE(children.count(), 0);
+ QCOMPARE(children.size(), 0);
}
void tst_QDialogButtonBox::removeButton_data()
@@ -387,31 +373,95 @@ void tst_QDialogButtonBox::removeButton()
QFETCH(QDialogButtonBox::ButtonRole, roleToAdd);
QDialogButtonBox buttonBox;
- QCOMPARE(buttonBox.buttons().count(), 0);
+ QCOMPARE(buttonBox.buttons().size(), 0);
QPushButton *button = new QPushButton("RemoveButton test");
buttonBox.addButton(button, roleToAdd);
- QTEST(int(buttonBox.buttons().count()), "expectedCount");
+ QTEST(int(buttonBox.buttons().size()), "expectedCount");
buttonBox.removeButton(button);
- QCOMPARE(buttonBox.buttons().count(), 0);
+ QCOMPARE(buttonBox.buttons().size(), 0);
delete button;
}
+#ifdef QT_BUILD_INTERNAL
+void tst_QDialogButtonBox::hideAndShowButton()
+{
+ if (QGuiApplication::styleHints()->tabFocusBehavior() == Qt::NoTabFocus)
+ QSKIP("Test skipped with Qt::NoTabFocus");
+
+ QDialogButtonBox buttonBox;
+ QDialogButtonBoxPrivate *d = static_cast<QDialogButtonBoxPrivate *>(QObjectPrivate::get(&buttonBox));
+ auto *apply = buttonBox.addButton( "Apply", QDialogButtonBox::ApplyRole );
+ auto *accept = buttonBox.addButton( "Accept", QDialogButtonBox::AcceptRole );
+ buttonBox.addButton( "Reject", QDialogButtonBox::RejectRole );
+ auto *widget = new QWidget();
+ auto *layout = new QHBoxLayout(widget);
+ layout->addWidget(&buttonBox);
+
+ // apply button shows first on macOS. accept button on all other OSes.
+ QAbstractButton *hideButton;
+#ifdef Q_OS_MACOS
+ hideButton = apply;
+ Q_UNUSED(accept);
+#else
+ hideButton = accept;
+ Q_UNUSED(apply);
+#endif
+
+ hideButton->hide();
+ widget->show();
+ QVERIFY(QTest::qWaitForWindowExposed(widget));
+ QTRY_VERIFY(buttonBox.focusWidget()); // QTBUG-114377: Without fixing, focusWidget() == nullptr
+ QCOMPARE(d->visibleButtons().count(), 2);
+ QCOMPARE(d->hiddenButtons.count(), 1);
+ QVERIFY(d->hiddenButtons.contains(hideButton));
+ QCOMPARE(buttonBox.buttons().count(), 3);
+ QSignalSpy spy(qApp, &QApplication::focusChanged);
+ QTest::sendKeyEvent(QTest::KeyAction::Click, &buttonBox, Qt::Key_Tab, QString(), Qt::KeyboardModifiers());
+ QCOMPARE(spy.count(), 1); // QTBUG-114377: Without fixing, tabbing wouldn't work.
+ hideButton->show();
+ QCOMPARE_GE(spy.count(), 1);
+ QTRY_COMPARE(QApplication::focusWidget(), hideButton);
+ QCOMPARE(d->visibleButtons().count(), 3);
+ QCOMPARE(d->hiddenButtons.count(), 0);
+ QCOMPARE(buttonBox.buttons().count(), 3);
+ spy.clear();
+ QTest::sendKeyEvent(QTest::KeyAction::Click, &buttonBox, Qt::Key_Backtab, QString(), Qt::KeyboardModifiers());
+ QCOMPARE(spy.count(), 1);
+}
+#endif
+
+void tst_QDialogButtonBox::hideAndShowStandardButton()
+{
+ QDialogButtonBox buttonBox;
+ buttonBox.setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+ buttonBox.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&buttonBox));
+ auto *button = buttonBox.button(QDialogButtonBox::Cancel);
+ QVERIFY(button);
+ button->hide();
+ QVERIFY(QTest::qWaitFor([button](){ return !button->isVisible(); }));
+ QCOMPARE(button, buttonBox.button(QDialogButtonBox::Cancel));
+ button->show();
+ QVERIFY(QTest::qWaitForWindowExposed(button));
+ QCOMPARE(button, buttonBox.button(QDialogButtonBox::Cancel));
+}
+
void tst_QDialogButtonBox::testDelete()
{
QDialogButtonBox buttonBox;
- QCOMPARE(buttonBox.buttons().count(), 0);
+ QCOMPARE(buttonBox.buttons().size(), 0);
QPushButton *deleteMe = new QPushButton("Happy");
buttonBox.addButton(deleteMe, QDialogButtonBox::HelpRole);
- QCOMPARE(buttonBox.buttons().count(), 1);
+ QCOMPARE(buttonBox.buttons().size(), 1);
QList<QAbstractButton *> children = buttonBox.findChildren<QAbstractButton *>();
- QCOMPARE(children.count(), 1);
+ QCOMPARE(children.size(), 1);
delete deleteMe;
children = buttonBox.findChildren<QAbstractButton *>();
- QCOMPARE(children.count(), 0);
- QCOMPARE(buttonBox.buttons().count(), 0);
+ QCOMPARE(children.size(), 0);
+ QCOMPARE(buttonBox.buttons().size(), 0);
}
class ObjectDeleter : public QObject
@@ -433,7 +483,7 @@ void tst_QDialogButtonBox::testSignalEmissionAfterDelete_QTBUG_45835()
{
{
QDialogButtonBox buttonBox;
- QCOMPARE(buttonBox.buttons().count(), 0);
+ QCOMPARE(buttonBox.buttons().size(), 0);
QSignalSpy buttonClickedSpy(&buttonBox, &QDialogButtonBox::clicked);
QVERIFY(buttonClickedSpy.isValid());
@@ -442,21 +492,21 @@ void tst_QDialogButtonBox::testSignalEmissionAfterDelete_QTBUG_45835()
QVERIFY(buttonBoxAcceptedSpy.isValid());
QPushButton *button = buttonBox.addButton("Test", QDialogButtonBox::AcceptRole);
- QCOMPARE(buttonBox.buttons().count(), 1);
+ QCOMPARE(buttonBox.buttons().size(), 1);
ObjectDeleter objectDeleter;
connect(&buttonBox, &QDialogButtonBox::clicked, &objectDeleter, &ObjectDeleter::deleteButton);
button->click();
- QCOMPARE(buttonBox.buttons().count(), 0);
- QCOMPARE(buttonClickedSpy.count(), 1);
- QCOMPARE(buttonBoxAcceptedSpy.count(), 1);
+ QCOMPARE(buttonBox.buttons().size(), 0);
+ QCOMPARE(buttonClickedSpy.size(), 1);
+ QCOMPARE(buttonBoxAcceptedSpy.size(), 1);
}
{
QPointer<QDialogButtonBox> buttonBox(new QDialogButtonBox);
- QCOMPARE(buttonBox->buttons().count(), 0);
+ QCOMPARE(buttonBox->buttons().size(), 0);
QSignalSpy buttonClickedSpy(buttonBox.data(), &QDialogButtonBox::clicked);
QVERIFY(buttonClickedSpy.isValid());
@@ -465,7 +515,7 @@ void tst_QDialogButtonBox::testSignalEmissionAfterDelete_QTBUG_45835()
QVERIFY(buttonBoxAcceptedSpy.isValid());
QPushButton *button = buttonBox->addButton("Test", QDialogButtonBox::AcceptRole);
- QCOMPARE(buttonBox->buttons().count(), 1);
+ QCOMPARE(buttonBox->buttons().size(), 1);
ObjectDeleter objectDeleter;
connect(buttonBox.data(), &QDialogButtonBox::clicked, &objectDeleter, &ObjectDeleter::deleteSender);
@@ -473,8 +523,8 @@ void tst_QDialogButtonBox::testSignalEmissionAfterDelete_QTBUG_45835()
button->click();
QVERIFY(buttonBox.isNull());
- QCOMPARE(buttonClickedSpy.count(), 1);
- QCOMPARE(buttonBoxAcceptedSpy.count(), 0);
+ QCOMPARE(buttonClickedSpy.size(), 1);
+ QCOMPARE(buttonBoxAcceptedSpy.size(), 0);
}
}
@@ -482,24 +532,24 @@ void tst_QDialogButtonBox::testMultipleAdd()
{
// Add a button into the thing multiple times.
QDialogButtonBox buttonBox;
- QCOMPARE(buttonBox.buttons().count(), 0);
+ QCOMPARE(buttonBox.buttons().size(), 0);
QPushButton *button = new QPushButton("Foo away");
buttonBox.addButton(button, QDialogButtonBox::AcceptRole);
- QCOMPARE(buttonBox.buttons().count(), 1);
+ QCOMPARE(buttonBox.buttons().size(), 1);
QCOMPARE(buttonBox.buttonRole(button), QDialogButtonBox::AcceptRole);
buttonBox.addButton(button, QDialogButtonBox::AcceptRole);
- QCOMPARE(buttonBox.buttons().count(), 1);
+ QCOMPARE(buttonBox.buttons().size(), 1);
QCOMPARE(buttonBox.buttonRole(button), QDialogButtonBox::AcceptRole);
// Add it again with a different role
buttonBox.addButton(button, QDialogButtonBox::RejectRole);
- QCOMPARE(buttonBox.buttons().count(), 1);
+ QCOMPARE(buttonBox.buttons().size(), 1);
QCOMPARE(buttonBox.buttonRole(button), QDialogButtonBox::RejectRole);
// Add it as an "invalid" role
buttonBox.addButton(button, QDialogButtonBox::InvalidRole);
- QCOMPARE(buttonBox.buttons().count(), 1);
+ QCOMPARE(buttonBox.buttons().size(), 1);
QCOMPARE(buttonBox.buttonRole(button), QDialogButtonBox::RejectRole);
}
@@ -619,13 +669,13 @@ void tst_QDialogButtonBox::testSignals()
if (clickMe)
clickMe->click();
- QTRY_COMPARE(clicked2.count(), clicked2Count);
- if (clicked2.count() > 0)
+ QTRY_COMPARE(clicked2.size(), clicked2Count);
+ if (clicked2.size() > 0)
QCOMPARE(qvariant_cast<QAbstractButton *>(clicked2.at(0).at(0)), clickMe);
- QTEST(int(accept.count()), "acceptCount");
- QTEST(int(reject.count()), "rejectCount");
- QTEST(int(helpRequested.count()), "helpRequestedCount");
+ QTEST(int(accept.size()), "acceptCount");
+ QTEST(int(reject.size()), "rejectCount");
+ QTEST(int(helpRequested.size()), "helpRequestedCount");
}
void tst_QDialogButtonBox::testSignalOrder()
@@ -781,7 +831,7 @@ void tst_QDialogButtonBox::testRemove()
button->click();
QTest::qWait(100);
- QCOMPARE(clicked.count(), 0);
+ QCOMPARE(clicked.size(), 0);
delete button;
}
@@ -843,7 +893,7 @@ void tst_QDialogButtonBox::task191642_default()
QVERIFY(QTest::qWaitForWindowActive(&dlg));
QVERIFY(def->isDefault());
QTest::keyPress( &dlg, Qt::Key_Enter );
- QCOMPARE(clicked.count(), 1);
+ QCOMPARE(clicked.size(), 1);
}
void tst_QDialogButtonBox::testDeletedStandardButton()
@@ -863,5 +913,87 @@ void tst_QDialogButtonBox::testDeletedStandardButton()
QVERIFY(!buttonC);
}
+void tst_QDialogButtonBox::automaticDefaultButton()
+{
+ // Having a QDialogButtonBox inside a QDialog triggers Qt to
+ // enable autoDefault for QPushButtons inside the button box.
+ // Check that the logic for resolving a default button based
+ // on the Accept role is not overridden by the first button
+ // in the dialog (the focus proxy) taking focus, and hence
+ // stealing the default button state.
+
+ {
+ QDialog dialog;
+ QDialogButtonBox *bb = new QDialogButtonBox(&dialog);
+ // Force horizontal orientation, where we know the order between
+ // Reset and Accept roles are always the same for all layouts.
+ bb->setOrientation(Qt::Horizontal);
+ auto *okButton = bb->addButton(QDialogButtonBox::Ok);
+ auto *resetButton = bb->addButton(QDialogButtonBox::Reset);
+ // Double check our assumption about Reset being first
+ QCOMPARE(bb->layout()->itemAt(0)->widget(), resetButton);
+
+ dialog.show();
+ QVERIFY(QTest::qWaitForWindowActive(&dialog));
+
+ QVERIFY(okButton->isDefault());
+ QSignalSpy buttonClicked(okButton, &QPushButton::clicked);
+ QTest::keyPress(&dialog, Qt::Key_Enter);
+ QCOMPARE(buttonClicked.count(), 1);
+ }
+
+ // However, if an explicit button has been focused, we respect that.
+
+ {
+ QDialog dialog;
+ QDialogButtonBox *bb = new QDialogButtonBox(&dialog);
+ bb->setOrientation(Qt::Horizontal);
+ bb->addButton(QDialogButtonBox::Ok);
+ auto *resetButton = bb->addButton(QDialogButtonBox::Reset);
+ resetButton->setFocus();
+ dialog.show();
+ QVERIFY(QTest::qWaitForWindowActive(&dialog));
+
+ QVERIFY(resetButton->isDefault());
+ QSignalSpy buttonClicked(resetButton, &QPushButton::clicked);
+ QTest::keyPress(&dialog, Qt::Key_Enter);
+ QCOMPARE(buttonClicked.count(), 1);
+ }
+}
+
+void tst_QDialogButtonBox::initialFocus_data()
+{
+ QTest::addColumn<Qt::FocusPolicy>("focusPolicy");
+ QTest::addColumn<bool>("lineEditHasFocus");
+
+ QTest::addRow("TabFocus") << Qt::FocusPolicy::TabFocus << false;
+ QTest::addRow("StrongFocus") << Qt::FocusPolicy::StrongFocus << true;
+ QTest::addRow("NoFocus") << Qt::FocusPolicy::NoFocus << false;
+ QTest::addRow("ClickFocus") << Qt::FocusPolicy::ClickFocus << false;
+ QTest::addRow("WheelFocus") << Qt::FocusPolicy::WheelFocus << false;
+}
+
+void tst_QDialogButtonBox::initialFocus()
+{
+ QFETCH(const Qt::FocusPolicy, focusPolicy);
+ QFETCH(const bool, lineEditHasFocus);
+ QDialog dialog;
+ QVBoxLayout *layout = new QVBoxLayout(&dialog);
+ QLineEdit *lineEdit = new QLineEdit(&dialog);
+ lineEdit->setFocusPolicy(focusPolicy);
+ layout->addWidget(lineEdit);
+ QDialogButtonBox *dialogButtonBox = new QDialogButtonBox(&dialog);
+ layout->addWidget(dialogButtonBox);
+ dialogButtonBox->addButton(QDialogButtonBox::Reset);
+ const auto *firstAcceptButton = dialogButtonBox->addButton(QDialogButtonBox::Ok);
+ dialogButtonBox->addButton(QDialogButtonBox::Cancel);
+ dialog.show();
+ dialog.activateWindow();
+ if (lineEditHasFocus)
+ QTRY_VERIFY(lineEdit->hasFocus());
+ else
+ QTRY_VERIFY(firstAcceptButton->hasFocus());
+}
+
QTEST_MAIN(tst_QDialogButtonBox)
#include "tst_qdialogbuttonbox.moc"
diff --git a/tests/auto/widgets/widgets/qdockwidget/BLACKLIST b/tests/auto/widgets/widgets/qdockwidget/BLACKLIST
index 6a3b189939..8873589ff4 100644
--- a/tests/auto/widgets/widgets/qdockwidget/BLACKLIST
+++ b/tests/auto/widgets/widgets/qdockwidget/BLACKLIST
@@ -1,3 +1,36 @@
# QTBUG-87415
[task169808_setFloating]
android
+#
+# QDockWidget::isFloating() is flaky after state change on these OS
+[closeAndDelete]
+macos
+b2qt
+arm
+android
+
+# QTBUG-103091
+[floatingTabs]
+arm
+android
+qnx
+macos
+b2qt
+
+# QTBUG-103091
+[hoverWithoutDrop]
+arm
+android
+qnx
+macos
+b2qt
+
+# OSes are flaky because of unplugging and plugging requires
+# precise calculation of the title bar area for mouse emulation
+# That's not possible for floating dock widgets.
+[deleteFloatingTabWithSingleDockWidget]
+qnx
+b2qt
+arm
+android
+macos
diff --git a/tests/auto/widgets/widgets/qdockwidget/CMakeLists.txt b/tests/auto/widgets/widgets/qdockwidget/CMakeLists.txt
index adf48ddb11..21d8fb60cc 100644
--- a/tests/auto/widgets/widgets/qdockwidget/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qdockwidget/CMakeLists.txt
@@ -1,13 +1,21 @@
-# Generated from qdockwidget.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qdockwidget Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qdockwidget LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qdockwidget
SOURCES
tst_qdockwidget.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
+ Qt::Core
Qt::CorePrivate
Qt::Gui
Qt::GuiPrivate
diff --git a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp
index d726807b7c..63a432578e 100644
--- a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp
+++ b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp
@@ -1,42 +1,25 @@
-/****************************************************************************
-**
-** 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>
#include <QSignalSpy>
-
#include <qaction.h>
#include <qdockwidget.h>
#include <qmainwindow.h>
+#include "private/qdockwidget_p.h"
+#include "private/qmainwindowlayout_p.h"
+#include <QAbstractButton>
#include <qlineedit.h>
+#include <QtGui/qpa/qplatformwindow.h>
#include <qtabbar.h>
#include <QScreen>
+#include <QTimer>
#include <QtGui/QPainter>
-#include "private/qdockwidget_p.h"
+#include <QLabel>
+
+Q_LOGGING_CATEGORY(lcTestDockWidget, "qt.widgets.tests.qdockwidget")
+
+#include <QtWidgets/private/qapplication_p.h>
bool hasFeature(QDockWidget *dockwidget, QDockWidget::DockWidgetFeature feature)
{ return (dockwidget->features() & feature) == feature; }
@@ -70,6 +53,7 @@ private slots:
void restoreDockWidget();
void restoreStateWhileStillFloating();
void setWindowTitle();
+
// task specific tests:
void task165177_deleteFocusWidget();
void task169808_setFloating();
@@ -78,6 +62,98 @@ private slots:
void task258459_visibilityChanged();
void taskQTBUG_1665_closableChanged();
void taskQTBUG_9758_undockedGeometry();
+
+ // Dock area permissions for DockWidgets and DockWidgetGroupWindows
+ void dockPermissions();
+
+ // test floating tabs, item_tree and window title consistency
+ void floatingTabs();
+ void hoverWithoutDrop();
+
+ // floating tab gets removed, when last child goes away
+ void deleteFloatingTabWithSingleDockWidget_data();
+ void deleteFloatingTabWithSingleDockWidget();
+
+ // test hide & show
+ void hideAndShow();
+
+ // test closing and deleting consistency
+ void closeAndDelete();
+ void closeUnclosable();
+
+ // test save and restore consistency
+ void saveAndRestore();
+
+private:
+ // helpers and consts for dockPermissions, hideAndShow, closeAndDelete
+#ifdef QT_BUILD_INTERNAL
+ void createTestWidgets(QMainWindow* &MainWindow, QPointer<QWidget> &cent,
+ QPointer<QDockWidget> &d1, QPointer<QDockWidget> &d2) const;
+
+ void unplugAndResize(QMainWindow* MainWindow, QDockWidget* dw, QPoint home, QSize size) const;
+
+ void createFloatingTabs(QMainWindow* &MainWindow, QPointer<QWidget> &cent,
+ QPointer<QDockWidget> &d1, QPointer<QDockWidget> &d2,
+ QList<int> &path1, QList<int> &path2) const;
+
+ static inline QPoint dragPoint(QDockWidget* dockWidget);
+ static inline QPoint home1(QMainWindow* MainWindow)
+ { return MainWindow->mapToGlobal(MainWindow->rect().topLeft() + QPoint(0.1 * MainWindow->width(), 0.1 * MainWindow->height())); }
+
+ static inline QPoint home2(QMainWindow* MainWindow)
+ { return MainWindow->mapToGlobal(MainWindow->rect().topLeft() + QPoint(0.6 * MainWindow->width(), 0.15 * MainWindow->height())); }
+
+ static inline QSize size1(QMainWindow* MainWindow)
+ { return QSize (0.2 * MainWindow->width(), 0.25 * MainWindow->height()); }
+
+ static inline QSize size2(QMainWindow* MainWindow)
+ { return QSize (0.1 * MainWindow->width(), 0.15 * MainWindow->height()); }
+
+ static inline QPoint dockPoint(QMainWindow* mw, Qt::DockWidgetArea area)
+ { return mw->mapToGlobal(qobject_cast<QMainWindowLayout*>(mw->layout())->dockWidgetAreaRect(area, QMainWindowLayout::Maximum).center()); }
+
+ bool checkFloatingTabs(QMainWindow* MainWindow, QPointer<QDockWidgetGroupWindow> &ftabs, const QList<QDockWidget*> &dwList = {}) const;
+
+ // move a dock widget
+ enum class MoveDockWidgetRule {
+ Drop,
+ Abort
+ };
+
+ void moveDockWidget(QDockWidget* dw, QPoint to, QPoint from, MoveDockWidgetRule rule) const;
+
+#ifdef QT_BUILD_INTERNAL
+ // Message handling for xcb error QTBUG 82059
+ static void xcbMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg);
+
+ enum class ChildRemovalReason {
+ Destroyed,
+ Closed,
+ Reparented
+ };
+
+public:
+ bool xcbError = false;
+ bool platformSupportingRaise = true;
+#endif
+private:
+
+#ifdef QT_DEBUG
+ // Grace time between mouse events. Set to 400 for debugging.
+ const int waitingTime = 400;
+
+ // Waiting time before closing widgets successful test. Set to 20000 for debugging.
+ const int waitBeforeClose = 0;
+
+ // Enable logging
+ const bool dockWidgetLog = true;
+#else
+ const int waitingTime = 15;
+ const int waitBeforeClose = 0;
+ const bool dockWidgetLog = false;
+#endif // QT_DEBUG
+#endif // QT_BUILD_INTERNAL
+
};
// Testing get/set functions
@@ -219,12 +295,12 @@ void tst_QDockWidget::features()
QVERIFY(!hasFeature(&dw, QDockWidget::DockWidgetClosable));
QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetMovable));
QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetFloatable));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE((int)*(static_cast<const QDockWidget::DockWidgetFeature *>(spy.at(0).value(0).constData())),
(int)dw.features());
spy.clear();
dw.setFeatures(dw.features());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
spy.clear();
setFeature(&dw, QDockWidget::DockWidgetClosable);
@@ -232,12 +308,12 @@ void tst_QDockWidget::features()
QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable));
QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetMovable));
QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetFloatable));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE((int)*static_cast<const QDockWidget::DockWidgetFeature *>(spy.at(0).value(0).constData()),
(int)dw.features());
spy.clear();
dw.setFeatures(dw.features());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
spy.clear();
setFeature(&dw, QDockWidget::DockWidgetMovable, false);
@@ -245,12 +321,12 @@ void tst_QDockWidget::features()
QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable));
QVERIFY(!hasFeature(&dw, QDockWidget::DockWidgetMovable));
QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetFloatable));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE((int)*static_cast<const QDockWidget::DockWidgetFeature *>(spy.at(0).value(0).constData()),
(int)dw.features());
spy.clear();
dw.setFeatures(dw.features());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
spy.clear();
setFeature(&dw, QDockWidget::DockWidgetMovable);
@@ -258,12 +334,12 @@ void tst_QDockWidget::features()
QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable));
QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetMovable));
QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetFloatable));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE((int)*static_cast<const QDockWidget::DockWidgetFeature *>(spy.at(0).value(0).constData()),
(int)dw.features());
spy.clear();
dw.setFeatures(dw.features());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
spy.clear();
setFeature(&dw, QDockWidget::DockWidgetFloatable, false);
@@ -271,12 +347,12 @@ void tst_QDockWidget::features()
QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable));
QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetMovable));
QVERIFY(!hasFeature(&dw, QDockWidget::DockWidgetFloatable));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE((int)*static_cast<const QDockWidget::DockWidgetFeature *>(spy.at(0).value(0).constData()),
(int)dw.features());
spy.clear();
dw.setFeatures(dw.features());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
spy.clear();
setFeature(&dw, QDockWidget::DockWidgetFloatable);
@@ -284,12 +360,12 @@ void tst_QDockWidget::features()
QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable));
QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetMovable));
QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetFloatable));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE((int)*static_cast<const QDockWidget::DockWidgetFeature *>(spy.at(0).value(0).constData()),
(int)dw.features());
spy.clear();
dw.setFeatures(dw.features());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
spy.clear();
// set all at once
@@ -298,12 +374,12 @@ void tst_QDockWidget::features()
QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable));
QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetMovable));
QVERIFY(!hasFeature(&dw, QDockWidget::DockWidgetFloatable));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE((int)*static_cast<const QDockWidget::DockWidgetFeature *>(spy.at(0).value(0).constData()),
(int)dw.features());
spy.clear();
dw.setFeatures(dw.features());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
spy.clear();
dw.setFeatures(QDockWidget::DockWidgetClosable);
@@ -311,12 +387,12 @@ void tst_QDockWidget::features()
QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable));
QVERIFY(!hasFeature(&dw, QDockWidget::DockWidgetMovable));
QVERIFY(!hasFeature(&dw, QDockWidget::DockWidgetFloatable));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE((int)*static_cast<const QDockWidget::DockWidgetFeature *>(spy.at(0).value(0).constData()),
(int)dw.features());
spy.clear();
dw.setFeatures(dw.features());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
spy.clear();
dw.setFeatures(allDockWidgetFeatures);
@@ -324,12 +400,12 @@ void tst_QDockWidget::features()
QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable));
QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetMovable));
QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetFloatable));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE((int)*static_cast<const QDockWidget::DockWidgetFeature *>(spy.at(0).value(0).constData()),
(int)dw.features());
spy.clear();
dw.setFeatures(dw.features());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
spy.clear();
}
@@ -356,20 +432,20 @@ void tst_QDockWidget::setFloating()
QVERIFY((dockedPosition - floatingPosition).manhattanLength() < 50);
QVERIFY(dw.isFloating());
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.at(0).value(0).toBool(), dw.isFloating());
spy.clear();
dw.setFloating(dw.isFloating());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
spy.clear();
dw.setFloating(false);
QVERIFY(!dw.isFloating());
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.at(0).value(0).toBool(), dw.isFloating());
spy.clear();
dw.setFloating(dw.isFloating());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
spy.clear();
}
@@ -393,12 +469,12 @@ void tst_QDockWidget::allowedAreas()
QVERIFY(!dw.isAreaAllowed(Qt::RightDockWidgetArea));
QVERIFY(!dw.isAreaAllowed(Qt::TopDockWidgetArea));
QVERIFY(!dw.isAreaAllowed(Qt::BottomDockWidgetArea));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const Qt::DockWidgetAreas *>(spy.at(0).value(0).constData()),
dw.allowedAreas());
spy.clear();
dw.setAllowedAreas(dw.allowedAreas());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
dw.setAllowedAreas(Qt::RightDockWidgetArea);
QCOMPARE(dw.allowedAreas(), Qt::RightDockWidgetArea);
@@ -406,12 +482,12 @@ void tst_QDockWidget::allowedAreas()
QVERIFY(dw.isAreaAllowed(Qt::RightDockWidgetArea));
QVERIFY(!dw.isAreaAllowed(Qt::TopDockWidgetArea));
QVERIFY(!dw.isAreaAllowed(Qt::BottomDockWidgetArea));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const Qt::DockWidgetAreas *>(spy.at(0).value(0).constData()),
dw.allowedAreas());
spy.clear();
dw.setAllowedAreas(dw.allowedAreas());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
dw.setAllowedAreas(Qt::TopDockWidgetArea);
QCOMPARE(dw.allowedAreas(), Qt::TopDockWidgetArea);
@@ -419,12 +495,12 @@ void tst_QDockWidget::allowedAreas()
QVERIFY(!dw.isAreaAllowed(Qt::RightDockWidgetArea));
QVERIFY(dw.isAreaAllowed(Qt::TopDockWidgetArea));
QVERIFY(!dw.isAreaAllowed(Qt::BottomDockWidgetArea));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const Qt::DockWidgetAreas *>(spy.at(0).value(0).constData()),
dw.allowedAreas());
spy.clear();
dw.setAllowedAreas(dw.allowedAreas());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
dw.setAllowedAreas(Qt::BottomDockWidgetArea);
QCOMPARE(dw.allowedAreas(), Qt::BottomDockWidgetArea);
@@ -432,12 +508,12 @@ void tst_QDockWidget::allowedAreas()
QVERIFY(!dw.isAreaAllowed(Qt::RightDockWidgetArea));
QVERIFY(!dw.isAreaAllowed(Qt::TopDockWidgetArea));
QVERIFY(dw.isAreaAllowed(Qt::BottomDockWidgetArea));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const Qt::DockWidgetAreas *>(spy.at(0).value(0).constData()),
dw.allowedAreas());
spy.clear();
dw.setAllowedAreas(dw.allowedAreas());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
// multiple dock window areas
dw.setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
@@ -446,12 +522,13 @@ void tst_QDockWidget::allowedAreas()
QVERIFY(!dw.isAreaAllowed(Qt::RightDockWidgetArea));
QVERIFY(dw.isAreaAllowed(Qt::TopDockWidgetArea));
QVERIFY(dw.isAreaAllowed(Qt::BottomDockWidgetArea));
- QCOMPARE(spy.count(), 1);
+ //QVERIFY(!dw.isAreaAllowed(Qt::FloatingDockWidgetArea));
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const Qt::DockWidgetAreas *>(spy.at(0).value(0).constData()),
dw.allowedAreas());
spy.clear();
dw.setAllowedAreas(dw.allowedAreas());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
dw.setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
QCOMPARE(dw.allowedAreas(), Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
@@ -459,12 +536,13 @@ void tst_QDockWidget::allowedAreas()
QVERIFY(dw.isAreaAllowed(Qt::RightDockWidgetArea));
QVERIFY(!dw.isAreaAllowed(Qt::TopDockWidgetArea));
QVERIFY(!dw.isAreaAllowed(Qt::BottomDockWidgetArea));
- QCOMPARE(spy.count(), 1);
+ //QVERIFY(!dw.isAreaAllowed(Qt::FloatingDockWidgetArea));
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const Qt::DockWidgetAreas *>(spy.at(0).value(0).constData()),
dw.allowedAreas());
spy.clear();
dw.setAllowedAreas(dw.allowedAreas());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
dw.setAllowedAreas(Qt::TopDockWidgetArea | Qt::LeftDockWidgetArea);
QCOMPARE(dw.allowedAreas(), Qt::TopDockWidgetArea | Qt::LeftDockWidgetArea);
@@ -472,12 +550,28 @@ void tst_QDockWidget::allowedAreas()
QVERIFY(!dw.isAreaAllowed(Qt::RightDockWidgetArea));
QVERIFY(dw.isAreaAllowed(Qt::TopDockWidgetArea));
QVERIFY(!dw.isAreaAllowed(Qt::BottomDockWidgetArea));
- QCOMPARE(spy.count(), 1);
+ //QVERIFY(!dw.isAreaAllowed(Qt::FloatingDockWidgetArea));
+ QCOMPARE(spy.size(), 1);
+ QCOMPARE(*static_cast<const Qt::DockWidgetAreas *>(spy.at(0).value(0).constData()),
+ dw.allowedAreas());
+ spy.clear();
+ dw.setAllowedAreas(dw.allowedAreas());
+ QCOMPARE(spy.size(), 0);
+
+ //dw.setAllowedAreas(Qt::BottomDockWidgetArea | Qt::FloatingDockWidgetArea);
+ dw.setAllowedAreas(Qt::BottomDockWidgetArea);
+ //QCOMPARE(dw.allowedAreas(), Qt::BottomDockWidgetArea | Qt::FloatingDockWidgetArea);
+ QVERIFY(!dw.isAreaAllowed(Qt::LeftDockWidgetArea));
+ QVERIFY(!dw.isAreaAllowed(Qt::RightDockWidgetArea));
+ QVERIFY(!dw.isAreaAllowed(Qt::TopDockWidgetArea));
+ QVERIFY(dw.isAreaAllowed(Qt::BottomDockWidgetArea));
+ //QVERIFY(dw.isAreaAllowed(Qt::FloatingDockWidgetArea));
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const Qt::DockWidgetAreas *>(spy.at(0).value(0).constData()),
dw.allowedAreas());
spy.clear();
dw.setAllowedAreas(dw.allowedAreas());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
dw.setAllowedAreas(Qt::BottomDockWidgetArea | Qt::RightDockWidgetArea);
QCOMPARE(dw.allowedAreas(), Qt::BottomDockWidgetArea | Qt::RightDockWidgetArea);
@@ -485,12 +579,13 @@ void tst_QDockWidget::allowedAreas()
QVERIFY(dw.isAreaAllowed(Qt::RightDockWidgetArea));
QVERIFY(!dw.isAreaAllowed(Qt::TopDockWidgetArea));
QVERIFY(dw.isAreaAllowed(Qt::BottomDockWidgetArea));
- QCOMPARE(spy.count(), 1);
+ //QVERIFY(!dw.isAreaAllowed(Qt::FloatingDockWidgetArea));
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const Qt::DockWidgetAreas *>(spy.at(0).value(0).constData()),
dw.allowedAreas());
spy.clear();
dw.setAllowedAreas(dw.allowedAreas());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
}
void tst_QDockWidget::toggleViewAction()
@@ -518,65 +613,65 @@ void tst_QDockWidget::visibilityChanged()
mw.addDockWidget(Qt::LeftDockWidgetArea, &dw);
mw.show();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.at(0).at(0).toBool(), true);
spy.clear();
dw.hide();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.at(0).at(0).toBool(), false);
spy.clear();
dw.hide();
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
dw.show();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.at(0).at(0).toBool(), true);
spy.clear();
dw.show();
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
QDockWidget dw2;
mw.tabifyDockWidget(&dw, &dw2);
dw2.show();
dw2.raise();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.at(0).at(0).toBool(), false);
spy.clear();
dw2.hide();
qApp->processEvents();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.at(0).at(0).toBool(), true);
spy.clear();
dw2.show();
dw2.raise();
qApp->processEvents();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.at(0).at(0).toBool(), false);
spy.clear();
dw.raise();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.at(0).at(0).toBool(), true);
spy.clear();
dw.raise();
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
dw2.raise();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.at(0).at(0).toBool(), false);
spy.clear();
dw2.raise();
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
mw.addDockWidget(Qt::RightDockWidgetArea, &dw2);
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QCOMPARE(spy.at(0).at(0).toBool(), true);
}
@@ -603,6 +698,9 @@ void tst_QDockWidget::updateTabBarOnVisibilityChanged()
mw.tabifyDockWidget(dw1, dw2);
mw.tabifyDockWidget(dw2, dw3);
+ const auto list1 = QList<QDockWidget *>{dw1, dw2, dw3};
+ QCOMPARE(mw.tabifiedDockWidgets(dw0), list1);
+
QTabBar *tabBar = mw.findChild<QTabBar *>();
QVERIFY(tabBar);
tabBar->setCurrentIndex(2);
@@ -616,6 +714,8 @@ void tst_QDockWidget::updateTabBarOnVisibilityChanged()
dw1->hide();
QTRY_COMPARE(tabBar->count(), 2);
QCOMPARE(tabBar->currentIndex(), 0);
+
+ QCOMPARE(mw.tabifiedDockWidgets(dw2), {dw3});
}
Q_DECLARE_METATYPE(Qt::DockWidgetArea)
@@ -630,56 +730,56 @@ void tst_QDockWidget::dockLocationChanged()
QSignalSpy spy(&dw, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)));
mw.addDockWidget(Qt::LeftDockWidgetArea, &dw);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)),
Qt::LeftDockWidgetArea);
spy.clear();
mw.addDockWidget(Qt::LeftDockWidgetArea, &dw);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)),
Qt::LeftDockWidgetArea);
spy.clear();
mw.addDockWidget(Qt::RightDockWidgetArea, &dw);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)),
Qt::RightDockWidgetArea);
spy.clear();
mw.removeDockWidget(&dw);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
QDockWidget dw2;
dw2.setObjectName("dock2");
mw.addDockWidget(Qt::TopDockWidgetArea, &dw2);
mw.tabifyDockWidget(&dw2, &dw);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)),
Qt::TopDockWidgetArea);
spy.clear();
mw.splitDockWidget(&dw2, &dw, Qt::Horizontal);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)),
Qt::TopDockWidgetArea);
spy.clear();
dw.setFloating(true);
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)),
Qt::NoDockWidgetArea);
spy.clear();
dw.setFloating(false);
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)),
Qt::TopDockWidgetArea);
spy.clear();
QByteArray ba = mw.saveState();
mw.restoreState(ba);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)),
Qt::TopDockWidgetArea);
}
@@ -950,9 +1050,9 @@ void tst_QDockWidget::task258459_visibilityChanged()
QSignalSpy spy2(&dock2, SIGNAL(visibilityChanged(bool)));
win.show();
QVERIFY(QTest::qWaitForWindowActive(&win));
- QCOMPARE(spy1.count(), 1);
+ QCOMPARE(spy1.size(), 1);
QCOMPARE(spy1.first().first().toBool(), false); //dock1 is invisible
- QCOMPARE(spy2.count(), 1);
+ QCOMPARE(spy2.size(), 1);
QCOMPARE(spy2.first().first().toBool(), true); //dock1 is visible
}
@@ -1002,9 +1102,10 @@ void tst_QDockWidget::setWindowTitle()
QMainWindow window;
QDockWidget dock1(&window);
QDockWidget dock2(&window);
- const QString dock1Title = QStringLiteral("&Window");
- const QString dock2Title = QStringLiteral("&Modifiable Window [*]");
+ constexpr QLatin1StringView dock1Title("&Window");
+ constexpr QLatin1StringView dock2Title("&Modifiable Window [*]");
+ // Set title on docked dock widgets, before main window is shown
dock1.setWindowTitle(dock1Title);
dock2.setWindowTitle(dock2Title);
window.addDockWidget(Qt::RightDockWidgetArea, &dock1);
@@ -1015,6 +1116,7 @@ void tst_QDockWidget::setWindowTitle()
QCOMPARE(dock1.windowTitle(), dock1Title);
QCOMPARE(dock2.windowTitle(), dock2Title);
+ // Check if title remains unchanged when docking / undocking
dock1.setFloating(true);
dock1.show();
QVERIFY(QTest::qWaitForWindowExposed(&dock1));
@@ -1024,12 +1126,16 @@ void tst_QDockWidget::setWindowTitle()
dock1.setFloating(true);
dock1.show();
QVERIFY(QTest::qWaitForWindowExposed(&dock1));
- const QString changed = QStringLiteral("Changed ");
+
+ // Change a floating dock widget's title and check remains unchanged when docking
+ constexpr QLatin1StringView changed("Changed ");
dock1.setWindowTitle(QString(changed + dock1Title));
QCOMPARE(dock1.windowTitle(), QString(changed + dock1Title));
dock1.setFloating(false);
+ QVERIFY(QTest::qWaitFor([&dock1](){ return !dock1.windowHandle(); }));
QCOMPARE(dock1.windowTitle(), QString(changed + dock1Title));
+ // Test consistency after toggling modified and floating
dock2.setWindowModified(true);
QCOMPARE(dock2.windowTitle(), dock2Title);
dock2.setFloating(true);
@@ -1044,6 +1150,846 @@ void tst_QDockWidget::setWindowTitle()
dock2.show();
QVERIFY(QTest::qWaitForWindowExposed(&dock2));
QCOMPARE(dock2.windowTitle(), dock2Title);
+
+ // Test title change of a closed dock widget
+ static constexpr QLatin1StringView closedDock2("Closed D2");
+ dock2.close();
+ dock2.setWindowTitle(closedDock2);
+ QCOMPARE(dock2.windowTitle(), closedDock2);
+}
+
+// helpers for dockPermissions, hideAndShow, closeAndDelete
+#ifdef QT_BUILD_INTERNAL
+void tst_QDockWidget::createTestWidgets(QMainWindow* &mainWindow, QPointer<QWidget> &cent, QPointer<QDockWidget> &d1, QPointer<QDockWidget> &d2) const
+{
+ // Enable logging if required
+ if (dockWidgetLog)
+ QLoggingCategory::setFilterRules("qt.widgets.dockwidgets=true");
+
+ // Derive sizes and positions from primary screen
+ const QRect screen = QApplication::primaryScreen()->availableGeometry();
+ const QPoint m_topLeft = screen.topLeft();
+ const QSize s_mwindow = QApplication::primaryScreen()->availableSize() * 0.7;
+
+ mainWindow = new QMainWindow;
+ mainWindow->setMouseTracking(true);
+ mainWindow->setFixedSize(s_mwindow);
+ cent = new QWidget;
+ mainWindow->setCentralWidget(cent);
+ cent->setLayout(new QGridLayout);
+ cent->layout()->setContentsMargins(0, 0, 0, 0);
+ cent->setMinimumSize(0, 0);
+ mainWindow->setDockOptions(QMainWindow::AllowTabbedDocks | QMainWindow::GroupedDragging);
+ mainWindow->move(m_topLeft);
+
+ const int minWidth = QApplication::style()->pixelMetric(QStyle::PM_TitleBarHeight);
+ const QSize minSize(minWidth, 2 * minWidth);
+ d1 = new QDockWidget(mainWindow);
+ d1->setMinimumSize(minSize);
+ d1->setWindowTitle("I am D1");
+ d1->setObjectName("D1");
+ d1->setFeatures(QDockWidget::DockWidgetFeatureMask);
+ d1->setAllowedAreas(Qt::DockWidgetArea::AllDockWidgetAreas);
+
+ d2 = new QDockWidget(mainWindow);
+ d2->setMinimumSize(minSize);
+ d2->setWindowTitle("I am D2");
+ d2->setObjectName("D2");
+ d2->setFeatures(QDockWidget::DockWidgetFeatureMask);
+ d2->setAllowedAreas(Qt::DockWidgetArea::RightDockWidgetArea);
+
+ mainWindow->addDockWidget(Qt::DockWidgetArea::LeftDockWidgetArea, d1);
+ mainWindow->addDockWidget(Qt::DockWidgetArea::RightDockWidgetArea, d2);
+ d1->show();
+ d2->show();
+ mainWindow->show();
+ QApplicationPrivate::setActiveWindow(mainWindow);
+
+}
+
+QPoint tst_QDockWidget::dragPoint(QDockWidget* dockWidget)
+{
+ Q_ASSERT(dockWidget);
+ QDockWidgetLayout *dwlayout = qobject_cast<QDockWidgetLayout *>(dockWidget->layout());
+ Q_ASSERT(dwlayout);
+ return dockWidget->mapToGlobal(dwlayout->titleArea().center());
+}
+
+void tst_QDockWidget::moveDockWidget(QDockWidget* dw, QPoint to, QPoint from, MoveDockWidgetRule rule) const
+{
+ Q_ASSERT(dw);
+
+ // If no from point is given, use the drag point
+ if (from.isNull())
+ from = dragPoint(dw);
+
+ // move and log
+ const QPoint source = dw->mapFromGlobal(from);
+ const QPoint target = dw->mapFromGlobal(to);
+ qCDebug(lcTestDockWidget) << "Move" << dw->objectName() << "from" << source;
+ qCDebug(lcTestDockWidget) << "Move" << dw->objectName() << "from" << from;
+ QTest::mousePress(dw, Qt::LeftButton, Qt::KeyboardModifiers(), source);
+ QTest::mouseMove(dw, target);
+ qCDebug(lcTestDockWidget) << "Move" << dw->objectName() << "to" << target;
+ qCDebug(lcTestDockWidget) << "Move" << dw->objectName() << "to" << to;
+ if (rule == MoveDockWidgetRule::Drop) {
+ QTest::mouseRelease(dw, Qt::LeftButton, Qt::KeyboardModifiers(), target);
+ QTest::qWait(waitingTime);
+
+ // Verify WindowActive only for floating dock widgets
+ if (dw->isFloating())
+ QTRY_VERIFY(QTest::qWaitForWindowActive(dw));
+ return;
+ }
+ qCDebug(lcTestDockWidget) << "Aborting move and dropping at origin";
+
+ // Give animations some time
+ QTest::qWait(waitingTime);
+ QTest::mouseMove(dw, from);
+ QTest::mouseRelease(dw, Qt::LeftButton, Qt::KeyboardModifiers(), from);
+ QTest::qWait(waitingTime);
+}
+
+void tst_QDockWidget::unplugAndResize(QMainWindow* mainWindow, QDockWidget* dw, QPoint home, QSize size) const
+{
+ Q_ASSERT(mainWindow);
+ Q_ASSERT(dw);
+
+ // Return if floating
+ if (dw->isFloating())
+ return;
+
+ QMainWindowLayout* layout = qobject_cast<QMainWindowLayout*>(mainWindow->layout());
+ Qt::DockWidgetArea area = layout->dockWidgetArea(dw);
+
+ // calculate minimum lateral move to unplug a dock widget
+ const int unplugMargin = 80;
+ int my = 0;
+ int mx = 0;
+
+ switch (area) {
+ case Qt::LeftDockWidgetArea:
+ mx = unplugMargin;
+ break;
+ case Qt::TopDockWidgetArea:
+ my = unplugMargin;
+ break;
+ case Qt::RightDockWidgetArea:
+ mx = -unplugMargin;
+ break;
+ case Qt::BottomDockWidgetArea:
+ my = -unplugMargin;
+ break;
+ default:
+ return;
+ }
+
+ // Remember size for comparison with unplugged object
+#ifdef Q_OS_LINUX
+ const int pluggedWidth = dw->width();
+ const int pluggedHeight = dw->height();
+#endif
+
+ // unplug and resize a dock Widget
+ qCDebug(lcTestDockWidget) << "*** unplug and resize" << dw->objectName();
+ QPoint pos1 = dw->mapToGlobal(dw->rect().center());
+ pos1.rx() += mx;
+ pos1.ry() += my;
+ moveDockWidget(dw, pos1, dw->mapToGlobal(dw->rect().center()), MoveDockWidgetRule::Drop);
+ QTRY_VERIFY(dw->isFloating());
+
+ // Unplugged object's size may differ max. by 2x frame size
+#ifdef Q_OS_LINUX
+ const int xMargin = 2 * dw->frameSize().width();
+ const int yMargin = 2 * dw->frameSize().height();
+ QVERIFY(dw->height() - pluggedHeight <= xMargin);
+ QVERIFY(dw->width() - pluggedWidth <= yMargin);
+#endif
+
+ qCDebug(lcTestDockWidget) << "Resizing" << dw->objectName() << "to" << size;
+ dw->setFixedSize(size);
+ QTest::qWait(waitingTime);
+ qCDebug(lcTestDockWidget) << "Move" << dw->objectName() << "to its home" << dw->mapFromGlobal(home);
+ dw->move(home);
+}
+
+bool tst_QDockWidget::checkFloatingTabs(QMainWindow* mainWindow, QPointer<QDockWidgetGroupWindow> &ftabs, const QList<QDockWidget*> &dwList) const
+{
+ Q_ASSERT(mainWindow);
+
+ // Check if mainWindow has a floatingTab child
+ ftabs = mainWindow->findChild<QDockWidgetGroupWindow*>();
+ if (ftabs.isNull()) {
+ qCDebug(lcTestDockWidget) << "MainWindow has no DockWidgetGroupWindow" << mainWindow;
+ return false;
+ }
+
+ QTabBar* tab = ftabs->findChild<QTabBar*>();
+ if (!tab) {
+ qCDebug(lcTestDockWidget) << "DockWidgetGroupWindow has no tab bar" << ftabs;
+ return false;
+ }
+
+ // both dock widgets must be direct children of the main window
+ const QList<QDockWidget*> children = ftabs->findChildren<QDockWidget*>(QString(), Qt::FindDirectChildrenOnly);
+ if (dwList.size() > 0)
+ {
+ if (dwList.size() != children.size()) {
+ qCDebug(lcTestDockWidget) << "Expected DockWidgetGroupWindow children:" << dwList.size()
+ << "Children found:" << children.size();
+
+ qCDebug(lcTestDockWidget) << "Expected:" << dwList;
+ qCDebug(lcTestDockWidget) << "Found in" << ftabs << ":" << children.size();
+ return false;
+ }
+
+ for (const QDockWidget* child : dwList) {
+ if (!children.contains(child)) {
+ qCDebug(lcTestDockWidget) << "Expected child" << child << "not found in" << children;
+ return false;
+ }
+ }
+ }
+
+ // Always select first tab position
+ qCDebug(lcTestDockWidget) << "click on first tab";
+ QTest::mouseClick(tab, Qt::LeftButton, Qt::KeyboardModifiers(), tab->tabRect(0).center());
+ return true;
+}
+
+#ifdef QT_BUILD_INTERNAL
+// Statics for xcb error, raise() suppert / msg handler
+static tst_QDockWidget *qThis = nullptr;
+static void (*oldMessageHandler)(QtMsgType, const QMessageLogContext &, const QString &);
+#define QXCBVERIFY(cond) do { if (xcbError) QSKIP("Test skipped due to XCB error"); QVERIFY(cond); } while (0)
+
+// detect xcb error and missing raise() support
+// qt.qpa.xcb: internal error: void QXcbWindow::setNetWmStateOnUnmappedWindow() called on mapped window
+void tst_QDockWidget::xcbMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
+{
+ Q_ASSERT(oldMessageHandler);
+
+ if (type == QtWarningMsg) {
+ Q_ASSERT(qThis);
+ if (QString(context.category) == "qt.qpa.xcb" && msg.contains("internal error"))
+ qThis->xcbError = true;
+ if (msg.contains("does not support raise"))
+ qThis->platformSupportingRaise = false;
+ }
+
+ return oldMessageHandler(type, context, msg);
+}
+#endif
+
+void tst_QDockWidget::createFloatingTabs(QMainWindow* &mainWindow, QPointer<QWidget> &cent,
+ QPointer<QDockWidget> &d1, QPointer<QDockWidget> &d2,
+ QList<int> &path1, QList<int> &path2) const
+{
+ createTestWidgets(mainWindow, cent, d1, d2);
+
+#ifdef QT_BUILD_INTERNAL
+ qThis = const_cast<tst_QDockWidget *>(this);
+ oldMessageHandler = qInstallMessageHandler(xcbMessageHandler);
+ auto resetMessageHandler = qScopeGuard([] { qInstallMessageHandler(oldMessageHandler); });
+#endif
+
+ // Test will fail if platform doesn't support raise.
+ mainWindow->windowHandle()->handle()->raise();
+ if (!platformSupportingRaise)
+ QSKIP("Platform not supporting raise(). Floating tab based tests will fail.");
+
+ // remember paths to d1 and d2
+ QMainWindowLayout* layout = qobject_cast<QMainWindowLayout *>(mainWindow->layout());
+ path1 = layout->layoutState.indexOf(d1);
+ path2 = layout->layoutState.indexOf(d2);
+
+ // unplug and resize both dock widgets
+ unplugAndResize(mainWindow, d1, home1(mainWindow), size1(mainWindow));
+ unplugAndResize(mainWindow, d2, home2(mainWindow), size2(mainWindow));
+
+ // docks must be parented to the main window, no group window must exist
+ QCOMPARE(d1->parentWidget(), mainWindow);
+ QCOMPARE(d2->parentWidget(), mainWindow);
+ QVERIFY(mainWindow->findChildren<QDockWidgetGroupWindow *>().isEmpty());
+
+ // Test plugging
+ qCDebug(lcTestDockWidget) << "*** move d1 dock over d2 dock ***";
+ qCDebug(lcTestDockWidget) << "**********(test plugging)*************";
+ qCDebug(lcTestDockWidget) << "Move d1 over d2";
+ moveDockWidget(d1, d2->mapToGlobal(d2->rect().center()), QPoint(), MoveDockWidgetRule::Drop);
+
+ // Now MainWindow has to have a floatingTab child
+ QPointer<QDockWidgetGroupWindow> ftabs;
+ QTRY_VERIFY(checkFloatingTabs(mainWindow, ftabs, QList<QDockWidget *>() << d1 << d2));
+}
+#endif // QT_BUILD_INTERNAL
+
+// test floating tabs and item_tree consistency
+void tst_QDockWidget::floatingTabs()
+{
+ if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
+ QSKIP("Test skipped on Wayland.");
+#ifdef Q_OS_WIN
+ QSKIP("Test skipped on Windows platforms");
+#endif // Q_OS_WIN
+#ifdef QT_BUILD_INTERNAL
+ // Create a mainwindow with a central widget and two dock widgets
+ QPointer<QDockWidget> d1;
+ QPointer<QDockWidget> d2;
+ QPointer<QWidget> cent;
+ QMainWindow* mainWindow;
+ QList<int> path1;
+ QList<int> path2;
+ createFloatingTabs(mainWindow, cent, d1, d2, path1, path2);
+ std::unique_ptr<QMainWindow> up_mainWindow(mainWindow);
+
+ QCOMPARE(mainWindow->tabifiedDockWidgets(d1), {d2});
+ QCOMPARE(mainWindow->tabifiedDockWidgets(d2), {d1});
+
+ /*
+ * unplug both dockwidgets, resize them and plug them into a joint floating tab
+ * expected behavior: QDOckWidgetGroupWindow with both widgets is created
+ */
+
+ // disabled due to flakiness on macOS and Windows
+ if (d1->isFloating())
+ qWarning("OS flakiness: D1 is docked and reports being floating");
+ if (d2->isFloating())
+ qWarning("OS flakiness: D2 is docked and reports being floating");
+
+ // Now MainWindow has to have a floatingTab child
+ QPointer<QDockWidgetGroupWindow> ftabs;
+ QTRY_VERIFY(checkFloatingTabs(mainWindow, ftabs, QList<QDockWidget *>() << d1 << d2));
+
+ // Hide both dock widgets. Verify that the group window is also hidden.
+ qCDebug(lcTestDockWidget) << "*** Hide and show tabbed dock widgets ***";
+ d1->hide();
+ d2->hide();
+ QTRY_VERIFY(ftabs->isHidden());
+
+ // Show both dockwidgets again. Verify that the group window is visible.
+ d1->show();
+ d2->show();
+ QTRY_VERIFY(ftabs->isVisible());
+
+ /*
+ * replug both dock widgets into their initial position
+ * expected behavior:
+ - both docks are plugged
+ - both docks are no longer floating
+ - title changes have been propagated
+ */
+
+
+ // limitation: QTest cannot handle drag to unplug.
+ // reason: Object under mouse mutates from QTabBar::tab to QDockWidget. QTest cannot handle that.
+ // => click float button to unplug
+ qCDebug(lcTestDockWidget) << "*** test unplugging from floating dock ***";
+
+ // QDockWidget must have a QAbstractButton with object name "qt_dockwidget_floatbutton"
+ QAbstractButton* floatButton = d1->findChild<QAbstractButton*>("qt_dockwidget_floatbutton", Qt::FindDirectChildrenOnly);
+ QTRY_VERIFY(floatButton != nullptr);
+ QPoint pos1 = floatButton->rect().center();
+ qCDebug(lcTestDockWidget) << "unplug d1" << pos1;
+ QTest::mouseClick(floatButton, Qt::LeftButton, Qt::KeyboardModifiers(), pos1);
+ QTest::qWait(waitingTime);
+
+ // d1 must be floating again, while d2 is still in its GroupWindow
+ QTRY_VERIFY(d1->isFloating());
+ QTRY_VERIFY(!d2->isFloating());
+
+ // Plug back into dock areas
+ qCDebug(lcTestDockWidget) << "*** test plugging back to dock areas ***";
+ qCDebug(lcTestDockWidget) << "Move d1 to left dock";
+ moveDockWidget(d1, dockPoint(mainWindow, Qt::LeftDockWidgetArea), QPoint(), MoveDockWidgetRule::Drop);
+ qCDebug(lcTestDockWidget) << "Move d2 to right dock";
+ moveDockWidget(d2, dockPoint(mainWindow, Qt::RightDockWidgetArea), QPoint(), MoveDockWidgetRule::Drop);
+
+ qCDebug(lcTestDockWidget) << "Waiting" << waitBeforeClose << "ms before plugging back.";
+ QTest::qWait(waitBeforeClose);
+
+ // Both dock widgets must no longer be floating
+ QTRY_VERIFY(!d1->isFloating());
+ QTRY_VERIFY(!d2->isFloating());
+
+ // check if QDockWidgetGroupWindow has been removed from mainWindowLayout and properly deleted
+ QTRY_VERIFY(!mainWindow->findChild<QDockWidgetGroupWindow*>());
+ QTRY_VERIFY(ftabs.isNull());
+
+ // Check if paths are consistent
+ QMainWindowLayout* layout = qobject_cast<QMainWindowLayout *>(mainWindow->layout());
+ qCDebug(lcTestDockWidget) << "Checking path consistency" << layout->layoutState.indexOf(d1) << layout->layoutState.indexOf(d2);
+
+ // Paths must be identical
+ QTRY_COMPARE(layout->layoutState.indexOf(d1), path1);
+ QTRY_COMPARE(layout->layoutState.indexOf(d2), path2);
+
+ QCOMPARE(mainWindow->tabifiedDockWidgets(d1), {});
+ QCOMPARE(mainWindow->tabifiedDockWidgets(d2), {});
+#else
+ QSKIP("test requires -developer-build option");
+#endif // QT_BUILD_INTERNAL
+}
+
+void tst_QDockWidget::deleteFloatingTabWithSingleDockWidget_data()
+{
+#ifdef QT_BUILD_INTERNAL
+ QTest::addColumn<int>("reason");
+ QTest::addRow("Delete child") << static_cast<int>(ChildRemovalReason::Destroyed);
+ QTest::addRow("Close child") << static_cast<int>(ChildRemovalReason::Closed);
+ QTest::addRow("Reparent child") << static_cast<int>(ChildRemovalReason::Reparented);
+#endif
+}
+
+void tst_QDockWidget::deleteFloatingTabWithSingleDockWidget()
+{
+ if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
+ QSKIP("Test skipped on Wayland.");
+#ifdef Q_OS_WIN
+ QSKIP("Test skipped on Windows platforms");
+#endif // Q_OS_WIN
+#ifdef QT_BUILD_INTERNAL
+
+ QFETCH(int, reason);
+ const ChildRemovalReason removalReason = static_cast<ChildRemovalReason>(reason);
+
+ QPointer<QDockWidget> d1;
+ QPointer<QDockWidget> d2;
+ QPointer<QWidget> cent;
+ QMainWindow* mainWindow;
+ QList<int> path1;
+ QList<int> path2;
+ createFloatingTabs(mainWindow, cent, d1, d2, path1, path2);
+ std::unique_ptr<QMainWindow> up_mainWindow(mainWindow);
+
+ switch (removalReason) {
+ case ChildRemovalReason::Destroyed:
+ delete d1;
+ break;
+ case ChildRemovalReason::Closed:
+ d1->close();
+ break;
+ case ChildRemovalReason::Reparented:
+ // This will create an invalid state, because setParent() doesn't fix the item_list.
+ // Testing this case anyway, because setParent() includig item_list fixup is executed,
+ // when the 2nd last dock widget is dragged out of a floating tab.
+ // => despite of the broken state, the group window has to be gone.
+ d1->setParent(mainWindow);
+ break;
+ }
+
+ QTRY_VERIFY(!qobject_cast<QDockWidgetGroupWindow *>(d2->parentWidget()));
+ QTRY_VERIFY(mainWindow->findChildren<QDockWidgetGroupWindow *>().isEmpty());
+#endif // QT_BUILD_INTERNAL
+}
+
+void tst_QDockWidget::hoverWithoutDrop()
+{
+ if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
+ QSKIP("Test skipped on Wayland.");
+#ifdef QT_BUILD_INTERNAL
+
+ QPointer<QDockWidget> d1;
+ QPointer<QDockWidget> d2;
+ QPointer<QWidget> cent;
+ QMainWindow* mainWindow;
+ createTestWidgets(mainWindow, cent, d1, d2);
+ std::unique_ptr<QMainWindow> up_mainWindow(mainWindow);
+
+ // unplug and resize both dock widgets
+ unplugAndResize(mainWindow, d1, home1(mainWindow), size1(mainWindow));
+ unplugAndResize(mainWindow, d2, home2(mainWindow), size2(mainWindow));
+
+ // Test plugging
+ qCDebug(lcTestDockWidget) << "*** move d1 dock over d2 dock ***";
+ qCDebug(lcTestDockWidget) << "*******(test hovering)***********";
+ qCDebug(lcTestDockWidget) << "Move d1 over d2, wait and return to origin";
+ const QPoint source = d1->mapToGlobal(d1->rect().center());
+ const QPoint target = d2->mapToGlobal(d2->rect().center());
+ moveDockWidget(d1, target, source, MoveDockWidgetRule::Abort);
+ auto *groupWindow = mainWindow->findChild<QDockWidgetGroupWindow *>();
+ QCOMPARE(groupWindow, nullptr);
+#else
+ QSKIP("test requires -developer-build option");
+#endif // QT_BUILD_INTERNAL
+}
+
+// test hide & show
+void tst_QDockWidget::hideAndShow()
+{
+ if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
+ QSKIP("Test skipped on Wayland.");
+#ifdef QT_BUILD_INTERNAL
+ // Skip test if xcb error is launched
+ qThis = this;
+ oldMessageHandler = qInstallMessageHandler(xcbMessageHandler);
+ auto resetMessageHandler = qScopeGuard([] { qInstallMessageHandler(oldMessageHandler); });
+
+ // Create a mainwindow with a central widget and two dock widgets
+ QPointer<QDockWidget> d1;
+ QPointer<QDockWidget> d2;
+ QPointer<QWidget> cent;
+ QMainWindow* mainWindow;
+ createTestWidgets(mainWindow, cent, d1, d2);
+ std::unique_ptr<QMainWindow> up_mainWindow(mainWindow);
+
+ // Check hiding of docked widgets
+ qCDebug(lcTestDockWidget) << "Hiding mainWindow with plugged dock widgets" << mainWindow;
+ mainWindow->hide();
+ QXCBVERIFY(!mainWindow->isVisible());
+ QXCBVERIFY(!d1->isVisible());
+ QXCBVERIFY(!d2->isVisible());
+
+ // Check showing everything again
+ qCDebug(lcTestDockWidget) << "Showing mainWindow with plugged dock widgets" << mainWindow;
+ mainWindow->show();
+ QXCBVERIFY(QTest::qWaitForWindowActive(mainWindow));
+ QXCBVERIFY(QTest::qWaitForWindowExposed(mainWindow));
+ QXCBVERIFY(mainWindow->isVisible());
+ QXCBVERIFY(QTest::qWaitForWindowActive(d1));
+ QXCBVERIFY(d1->isVisible());
+ QXCBVERIFY(QTest::qWaitForWindowActive(d2));
+ QXCBVERIFY(d2->isVisible());
+
+ // in case of XCB errors, unplugAndResize will block and cause the test to time out.
+ // => force skip
+ QTest::qWait(waitingTime);
+ if (xcbError)
+ QSKIP("Test skipped due to XCB error");
+
+ // unplug and resize both dock widgets
+ unplugAndResize(mainWindow, d1, home1(mainWindow), size1(mainWindow));
+ unplugAndResize(mainWindow, d2, home2(mainWindow), size2(mainWindow));
+
+ // Check hiding of undocked widgets
+ qCDebug(lcTestDockWidget) << "Hiding mainWindow with unplugged dock widgets" << mainWindow;
+ mainWindow->hide();
+ QTRY_VERIFY(!mainWindow->isVisible());
+ QTRY_VERIFY(d1->isVisible());
+ QTRY_VERIFY(d2->isVisible());
+ d1->hide();
+ d2->hide();
+ QTRY_VERIFY(!d1->isVisible());
+ QTRY_VERIFY(!d2->isVisible());
+
+
+ // Check floating, hidden dock widgets remain hidden, when their state is restored
+ qCDebug(lcTestDockWidget) << "Restoring state of unplugged, hidden dock widgets" << mainWindow;
+ const QByteArray state = mainWindow->saveState();
+ mainWindow->restoreState(state);
+ mainWindow->show();
+ QVERIFY(QTest::qWaitForWindowExposed(mainWindow));
+ QTRY_VERIFY(!d1->isVisible());
+ QTRY_VERIFY(!d2->isVisible());
+
+ qCDebug(lcTestDockWidget) << "Waiting" << waitBeforeClose << "ms before closing.";
+ QTest::qWait(waitBeforeClose);
+#else
+ QSKIP("test requires -developer-build option");
+#endif // QT_BUILD_INTERNAL
+}
+
+// test closing and deleting consistency
+void tst_QDockWidget::closeAndDelete()
+{
+ if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
+ QSKIP("Test skipped on Wayland.");
+#ifdef QT_BUILD_INTERNAL
+ // Create a mainwindow with a central widget and two dock widgets
+ QPointer<QDockWidget> d1;
+ QPointer<QDockWidget> d2;
+ QPointer<QWidget> cent;
+ QMainWindow* mainWindow;
+ createTestWidgets(mainWindow, cent, d1, d2);
+ std::unique_ptr<QMainWindow> up_mainWindow(mainWindow);
+
+ // unplug and resize both dock widgets
+ unplugAndResize(mainWindow, d1, home1(mainWindow), size1(mainWindow));
+ unplugAndResize(mainWindow, d2, home2(mainWindow), size2(mainWindow));
+
+ // Create a floating tab and unplug it again
+ qCDebug(lcTestDockWidget) << "Move d1 over d2";
+ moveDockWidget(d1, d2->mapToGlobal(d2->rect().center()), QPoint(), MoveDockWidgetRule::Drop);
+
+ // Both dock widgets must no longer be floating
+ // disabled due to flakiness on macOS and Windows
+ //QTRY_VERIFY(!d1->isFloating());
+ //QTRY_VERIFY(!d2->isFloating());
+ if (d1->isFloating())
+ qWarning("OS flakiness: D1 is docked and reports being floating");
+ if (d2->isFloating())
+ qWarning("OS flakiness: D2 is docked and reports being floating");
+
+ // Close everything with a single shot. Expected behavior: Event loop stops
+ QSignalSpy closeSpy(qApp, &QApplication::lastWindowClosed);
+ QObject localContext;
+
+ QTimer::singleShot(0, &localContext, [&](){
+ mainWindow->close();
+ QTRY_VERIFY(!mainWindow->isVisible());
+ QTRY_VERIFY(d1->isVisible());
+ QTRY_VERIFY(d2->isVisible());
+ d1->close();
+ d2->close();
+ QTRY_VERIFY(!d1->isVisible());
+ QTRY_VERIFY(!d2->isVisible());
+ QTRY_COMPARE(closeSpy.count(), 1);
+ QApplication::quit();
+ });
+
+ QApplication::exec();
+
+ // Check heap cleanup
+ qCDebug(lcTestDockWidget) << "Deleting mainWindow";
+ up_mainWindow.reset();
+ QTRY_VERIFY(d1.isNull());
+ QTRY_VERIFY(d2.isNull());
+ QTRY_VERIFY(cent.isNull());
+#else
+ QSKIP("test requires -developer-build option");
+#endif // QT_BUILD_INTERNAL
+}
+
+void tst_QDockWidget::closeUnclosable()
+{
+ QDockWidget *dockWidget = new QDockWidget("dock");
+ dockWidget->setWidget(new QScrollArea);
+ dockWidget->setFeatures(QDockWidget::DockWidgetFloatable);
+
+ QMainWindow mw;
+ mw.addDockWidget(Qt::TopDockWidgetArea, dockWidget);
+ mw.show();
+
+ QVERIFY(QTest::qWaitForWindowExposed(&mw));
+ dockWidget->setFloating(true);
+
+ QCOMPARE(dockWidget->close(), false);
+ mw.close();
+ QCOMPARE(dockWidget->close(), true);
+}
+
+// Test dock area permissions
+void tst_QDockWidget::dockPermissions()
+{
+ if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
+ QSKIP("Test skipped on Wayland.");
+#ifdef Q_OS_WIN
+ QSKIP("Test skipped on Windows platforms");
+#endif // Q_OS_WIN
+#ifdef QT_BUILD_INTERNAL
+ // Create a mainwindow with a central widget and two dock widgets
+ QPointer<QDockWidget> d1;
+ QPointer<QDockWidget> d2;
+ QPointer<QWidget> cent;
+ QMainWindow* mainWindow;
+ createTestWidgets(mainWindow, cent, d1, d2);
+ std::unique_ptr<QMainWindow> up_mainWindow(mainWindow);
+
+ /*
+ * Unplug both dock widgets from their dock areas and hover them over each other
+ * expected behavior:
+ * - d2 hovering over d1 does nothing as d2 can only use right dock
+ * - hovering d2 over top, left and bottom dock area will do nothing due to lacking permissions
+ * - d1 hovering over d2 will create floating tabs as d1 has permission for DockWidgetArea::FloatingDockWidgetArea
+ * - resizing and tab creation will add two gap items in the right dock (d2)
+ */
+
+ // unplug and resize both dock widgets
+ unplugAndResize(mainWindow, d1, home1(mainWindow), size1(mainWindow));
+ unplugAndResize(mainWindow, d2, home2(mainWindow), size2(mainWindow));
+
+ // both dock widgets must be direct children of the main window
+ {
+ const QList<QDockWidget*> children = mainWindow->findChildren<QDockWidget*>(QString(), Qt::FindDirectChildrenOnly);
+ QTRY_VERIFY(children.size() == 2);
+ for (const QDockWidget* child : children)
+ QTRY_VERIFY(child == d1 || child == d2);
+ }
+
+ // The main window must not contain floating tabs
+ QTRY_VERIFY(mainWindow->findChild<QDockWidgetGroupWindow*>() == nullptr);
+
+ // Test unpermitted dock areas with d2
+ qCDebug(lcTestDockWidget) << "*** move d2 to forbidden docks ***";
+
+ // Move d2 to non allowed dock areas and verify it remains floating
+ qCDebug(lcTestDockWidget) << "Move d2 to top dock";
+ moveDockWidget(d2, dockPoint(mainWindow, Qt::TopDockWidgetArea), QPoint(), MoveDockWidgetRule::Drop);
+ QTRY_VERIFY(d2->isFloating());
+
+ qCDebug(lcTestDockWidget) << "Move d2 to left dock";
+ //moveDockWidget(d2, d2->mapFrom(MainWindow, dockPoint(MainWindow, Qt::LeftDockWidgetArea)));
+ moveDockWidget(d2, dockPoint(mainWindow, Qt::LeftDockWidgetArea), QPoint(), MoveDockWidgetRule::Drop);
+ QTRY_VERIFY(d2->isFloating());
+
+ qCDebug(lcTestDockWidget) << "Move d2 to bottom dock";
+ moveDockWidget(d2, dockPoint(mainWindow, Qt::BottomDockWidgetArea), QPoint(), MoveDockWidgetRule::Drop);
+ QTRY_VERIFY(d2->isFloating());
+
+ qCDebug(lcTestDockWidget) << "Waiting" << waitBeforeClose << "ms before closing.";
+ QTest::qWait(waitBeforeClose);
+#else
+ QSKIP("test requires -developer-build option");
+#endif // QT_BUILD_INTERNAL
+}
+
+/*!
+ \internal
+
+ This test checks consistency of QMainWindow::saveState() / QMainWindow::restoreState().
+ These methods (de)serialize dock widget properties via a QDataStream into a QByteArray.
+
+ If the logic of (de)serializing Qt datatypes and classes changes, old settings can fail
+ to restore properly without triggering warnings or assertions.
+
+ The test consists of two parts:
+ \list 1
+ \li Read properties from a hard coded byte array and check if it is deserialized correctly.
+ \li Serialize properties into a \a QByteArray and check if it is serialized correctly.
+ \endlist
+*/
+void tst_QDockWidget::saveAndRestore()
+{
+ if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
+ QSKIP("Test skipped on Wayland.");
+#ifdef Q_OS_WIN
+ QSKIP("Test skipped on Windows platforms");
+#endif // Q_OS_WIN
+#ifndef QT_BUILD_INTERNAL
+ QSKIP("test requires -developer-build option");
+#else
+
+ // Hard coded byte array for test initialization
+ const QByteArray testArray = QByteArrayLiteral(
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\xFD\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x05\xE8\xFC\x02\x00\x00\x00\x01\xFB\x00\x00\x00\x04\x00"
+ "D\x00"
+ "1\x03\x00\x00\x01\f\x00\x00\x00\x97\x00\x00\x02\x19\x00\x00\x01z\x00\x00\x00\x01\x00\x00\x00\x13\x00\x00\x05\xE8\xFC\x02\x00\x00\x00\x01\xFB\x00\x00\x00\x04\x00"
+ "D\x00"
+ "2\x03\x00\x00\x06L\x00\x00\x00\xFF\x00\x00\x01\f\x00\x00\x00\xE2\x00\x00\n\x80\x00\x00\x05\xE8\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\b\x00\x00\x00\b\xFC\x00\x00\x00\x00"
+ );
+
+ QByteArray referenceArray; // Copy of testArray, corrected for current screen limits
+ QPoint topLeft1; // Top left point of dock widget d1
+ QPoint topLeft2; // Top left point of dock widget d2
+ QSize widgetSize1; // Size of dock widget d1
+ QSize widgetSize2; // Size of dock widget d2
+ bool isFloating1; // Floating status of dock widget d1
+ bool isFloating2; // Floating status of dock widget d2
+
+ // Create a mainwindow with a central widget and two dock widgets.
+ // Import properties from hard coded byte array.
+ // Use a scope to delete objects from screen after test.
+ {
+ QPointer<QDockWidget> d1;
+ QPointer<QDockWidget> d2;
+ QPointer<QWidget> cent;
+ QMainWindow* mainWindow;
+ createTestWidgets(mainWindow, cent, d1, d2);
+
+ // Failure to restore properties might lead to inconsistencies and crash.
+ // To leave a clean environment when the test inexpectedly goes out of scope,
+ // => store main window pointer in a std::unique_ptr
+ std::unique_ptr<QMainWindow> up_mainWindow(mainWindow);
+
+ // Restore, wait for events to be processed
+ mainWindow->restoreState(testArray);
+ QVERIFY(QTest::qWaitForWindowExposed(d1));
+ QVERIFY(QTest::qWaitForWindowExposed(d2));
+
+ // Serialized dock widget positions and sizes might be overridden due
+ // screen size limitations => do not check them here.
+ // If the test fails between here and scope end, serialization format/sequence have changed
+ QTRY_VERIFY(d1->isFloating());
+ QTRY_VERIFY(d2->isFloating());
+
+ // Hide main window and save their floating status.
+ // Reason:
+ // - KDE window managers do not take control over dock widgets.
+ // => They always close with the main window.
+ // - Some non KDE window managers do take control over dock widgets.
+ // => They prevent them from closing with the main window (QTBUG-103474).
+ // If properties are restored correctly, closing behavior must be consistent
+ // throughout this test.
+ mainWindow->hide();
+ // FIXME: No method exists in 6.5 to wait for a window to be hidden.
+ // => wait and hope the best, replace with qWaitForWindowHidden once implemented.
+ QTest::qWait(200);
+ isFloating1 = d1->isFloating();
+ isFloating2 = d2->isFloating();
+ }
+
+ // Create a mainwindow with a central widget and two dock widgets.
+ // Assign different properties to each dock widgets.
+ // Write properties to a byte array.
+ // Remember position and size properties for comparison.
+ // Use a scope to delete objects from screen after test.
+ {
+ QPointer<QDockWidget> d1;
+ QPointer<QDockWidget> d2;
+ QPointer<QWidget> cent;
+ QMainWindow* mainWindow;
+ createTestWidgets(mainWindow, cent, d1, d2);
+ std::unique_ptr<QMainWindow> up_mainWindow(mainWindow);
+
+ // unplug, position and resize both dock widgets relative to screen size
+ unplugAndResize(mainWindow, d1, home1(mainWindow), size1(mainWindow));
+ unplugAndResize(mainWindow, d2, home2(mainWindow), size2(mainWindow));
+
+ topLeft1 = d1->pos();
+ topLeft2 = d2->pos();
+ widgetSize1 = d1->size();
+ widgetSize2 = d2->size();
+
+ // save properties, potentially corrected for screen limits
+ referenceArray = mainWindow->saveState();
+
+ // Check closing behavior consistency
+ mainWindow->hide();
+ QTRY_VERIFY(d1->isFloating());
+ QTRY_VERIFY(d2->isFloating());
+ QCOMPARE(d1->isFloating(), isFloating1);
+ QCOMPARE(d2->isFloating(), isFloating2);
+ }
+
+ // Create a new main window, central window and two dock widgets.
+ QPointer<QDockWidget> d1;
+ QPointer<QDockWidget> d2;
+ QPointer<QWidget> cent;
+ QMainWindow* mainWindow;
+ createTestWidgets(mainWindow, cent, d1, d2);
+
+ // Failure to restore properties might lead to inconsistencies and crash.
+ // To leave a clean environment when the test inexpectedly goes out of scope,
+ // - store main window pointer in a std::unique_ptr
+ std::unique_ptr<QMainWindow> up_mainWindow(mainWindow);
+
+ // Restore properties and wait for events to be processed
+ mainWindow->restoreState(referenceArray);
+ QVERIFY(QTest::qWaitForWindowExposed(d1));
+ QVERIFY(QTest::qWaitForWindowExposed(d2));
+
+ // Compare positions, sizes and floating status
+ // If the test fails in the following 12 lines,
+ // the de-serialization format/sequence have changed
+ QCOMPARE(topLeft1, d1->pos());
+ QCOMPARE(topLeft2, d2->pos());
+ QCOMPARE(widgetSize1, d1->size());
+ QCOMPARE(widgetSize2, d2->size());
+ QVERIFY(d1->isFloating());
+ QVERIFY(d2->isFloating());
+
+ // Serialize again to compare all remaining properties
+ const QByteArray comparisonArray = mainWindow->saveState();
+ QCOMPARE(comparisonArray, referenceArray);
+
+ // Check closing behavior consistency
+ mainWindow->hide();
+ QTRY_VERIFY(d1->isFloating());
+ QTRY_VERIFY(d2->isFloating());
+ QCOMPARE(d1->isFloating(), isFloating1);
+ QCOMPARE(d2->isFloating(), isFloating2);
+
+#endif // QT_BUILD_INTERNAL
}
QTEST_MAIN(tst_QDockWidget)
diff --git a/tests/auto/widgets/widgets/qdoublespinbox/CMakeLists.txt b/tests/auto/widgets/widgets/qdoublespinbox/CMakeLists.txt
index 6be779bb81..b023174dc9 100644
--- a/tests/auto/widgets/widgets/qdoublespinbox/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qdoublespinbox/CMakeLists.txt
@@ -1,13 +1,21 @@
-# Generated from qdoublespinbox.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qdoublespinbox Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qdoublespinbox LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qdoublespinbox
SOURCES
tst_qdoublespinbox.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
+ Qt::WidgetsPrivate
)
diff --git a/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp b/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp
index dd67de2287..28752cd40d 100644
--- a/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp
+++ b/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.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>
@@ -47,6 +22,8 @@
#include <QStyle>
#include <QProxyStyle>
+#include <QtWidgets/private/qapplication_p.h>
+
class DoubleSpinBox : public QDoubleSpinBox
{
Q_OBJECT
@@ -880,8 +857,15 @@ void tst_QDoubleSpinBox::editingFinished()
testFocusWidget.show();
testFocusWidget.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&testFocusWidget));
+
+ box->show();
+ QVERIFY(QTest::qWaitForWindowExposed(box));
box->setFocus();
- QTRY_VERIFY(box->hasFocus());
+
+ // Box may fail to acquire focus due to a system popup
+ // it is fair in that case to skip the test
+ if (!QTest::qWaitForWindowActive(box))
+ QSKIP("Focus acquisition failed.");
QSignalSpy editingFinishedSpy1(box, SIGNAL(editingFinished()));
QSignalSpy editingFinishedSpy2(box2, SIGNAL(editingFinished()));
@@ -890,37 +874,37 @@ void tst_QDoubleSpinBox::editingFinished()
QTest::keyClick(box, Qt::Key_Up);
- QCOMPARE(editingFinishedSpy1.count(), 0);
- QCOMPARE(editingFinishedSpy2.count(), 0);
+ QCOMPARE(editingFinishedSpy1.size(), 0);
+ QCOMPARE(editingFinishedSpy2.size(), 0);
QTest::keyClick(box2, Qt::Key_Up);
QTest::keyClick(box2, Qt::Key_Up);
box2->setFocus();
- QCOMPARE(editingFinishedSpy1.count(), 1);
+ QCOMPARE(editingFinishedSpy1.size(), 1);
box->setFocus();
- QCOMPARE(editingFinishedSpy1.count(), 1);
- QCOMPARE(editingFinishedSpy2.count(), 1);
+ QCOMPARE(editingFinishedSpy1.size(), 1);
+ QCOMPARE(editingFinishedSpy2.size(), 1);
QTest::keyClick(box, Qt::Key_Up);
- QCOMPARE(editingFinishedSpy1.count(), 1);
- QCOMPARE(editingFinishedSpy2.count(), 1);
+ QCOMPARE(editingFinishedSpy1.size(), 1);
+ QCOMPARE(editingFinishedSpy2.size(), 1);
QTest::keyClick(box, Qt::Key_Enter);
- QCOMPARE(editingFinishedSpy1.count(), 2);
- QCOMPARE(editingFinishedSpy2.count(), 1);
+ QCOMPARE(editingFinishedSpy1.size(), 2);
+ QCOMPARE(editingFinishedSpy2.size(), 1);
QTest::keyClick(box, Qt::Key_Return);
- QCOMPARE(editingFinishedSpy1.count(), 3);
- QCOMPARE(editingFinishedSpy2.count(), 1);
+ QCOMPARE(editingFinishedSpy1.size(), 3);
+ QCOMPARE(editingFinishedSpy2.size(), 1);
box2->setFocus();
- QCOMPARE(editingFinishedSpy1.count(), 4);
- QCOMPARE(editingFinishedSpy2.count(), 1);
+ QCOMPARE(editingFinishedSpy1.size(), 4);
+ QCOMPARE(editingFinishedSpy2.size(), 1);
QTest::keyClick(box2, Qt::Key_Enter);
- QCOMPARE(editingFinishedSpy1.count(), 4);
- QCOMPARE(editingFinishedSpy2.count(), 2);
+ QCOMPARE(editingFinishedSpy1.size(), 4);
+ QCOMPARE(editingFinishedSpy2.size(), 2);
QTest::keyClick(box2, Qt::Key_Return);
- QCOMPARE(editingFinishedSpy1.count(), 4);
- QCOMPARE(editingFinishedSpy2.count(), 3);
+ QCOMPARE(editingFinishedSpy1.size(), 4);
+ QCOMPARE(editingFinishedSpy2.size(), 3);
testFocusWidget.hide();
- QCOMPARE(editingFinishedSpy1.count(), 4);
- QCOMPARE(editingFinishedSpy2.count(), 4);
+ QCOMPARE(editingFinishedSpy1.size(), 4);
+ QCOMPARE(editingFinishedSpy2.size(), 4);
}
void tst_QDoubleSpinBox::removeAll()
@@ -1170,7 +1154,7 @@ void tst_QDoubleSpinBox::taskQTBUG_5008_textFromValueAndValidate()
spinbox.show();
spinbox.activateWindow();
spinbox.setFocus();
- QApplication::setActiveWindow(&spinbox);
+ QApplicationPrivate::setActiveWindow(&spinbox);
QVERIFY(QTest::qWaitForWindowActive(&spinbox));
QCOMPARE(static_cast<QWidget *>(&spinbox), QApplication::activeWindow());
QTRY_VERIFY(spinbox.hasFocus());
@@ -1776,12 +1760,12 @@ void tst_QDoubleSpinBox::stepModifierPressAndHold()
QStyle::CC_SpinBox, &spinBoxStyleOption, subControl, &spin);
QTest::mousePress(&spin, Qt::LeftButton, modifiers, buttonRect.center());
- QTRY_VERIFY(spy.length() >= 3);
+ QTRY_VERIFY(spy.size() >= 3);
QTest::mouseRelease(&spin, Qt::LeftButton, modifiers, buttonRect.center());
const auto value = spy.last().at(0);
QVERIFY(value.userType() == QMetaType::Double);
- QCOMPARE(value.toDouble(), spy.length() * expectedStepModifier);
+ QCOMPARE(value.toDouble(), spy.size() * expectedStepModifier);
}
QTEST_MAIN(tst_QDoubleSpinBox)
diff --git a/tests/auto/widgets/widgets/qfocusframe/CMakeLists.txt b/tests/auto/widgets/widgets/qfocusframe/CMakeLists.txt
index d5e32e9337..5e2f3bd955 100644
--- a/tests/auto/widgets/widgets/qfocusframe/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qfocusframe/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qfocusframe.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qfocusframe Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qfocusframe LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qfocusframe
SOURCES
tst_qfocusframe.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
)
diff --git a/tests/auto/widgets/widgets/qfocusframe/tst_qfocusframe.cpp b/tests/auto/widgets/widgets/qfocusframe/tst_qfocusframe.cpp
index d273d77e35..560ba686cc 100644
--- a/tests/auto/widgets/widgets/qfocusframe/tst_qfocusframe.cpp
+++ b/tests/auto/widgets/widgets/qfocusframe/tst_qfocusframe.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>
@@ -95,7 +70,7 @@ void tst_QFocusFrame::focusFrameInsideScrollview()
window.show();
QFocusFrame *focusFrame = nullptr;
- QTRY_VERIFY(focusFrame = window.findChild<QFocusFrame *>());
+ QTRY_VERIFY((focusFrame = window.findChild<QFocusFrame *>()));
const QPoint initialOffset = focusFrame->widget()->mapToGlobal(QPoint()) - focusFrame->mapToGlobal(QPoint());
tableView.scrollTo(itemModel->index(40, 0));
diff --git a/tests/auto/widgets/widgets/qfontcombobox/CMakeLists.txt b/tests/auto/widgets/widgets/qfontcombobox/CMakeLists.txt
index 869666cb19..15dad99b9c 100644
--- a/tests/auto/widgets/widgets/qfontcombobox/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qfontcombobox/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qfontcombobox.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qfontcombobox Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qfontcombobox LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qfontcombobox
SOURCES
tst_qfontcombobox.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
)
diff --git a/tests/auto/widgets/widgets/qfontcombobox/tst_qfontcombobox.cpp b/tests/auto/widgets/widgets/qfontcombobox/tst_qfontcombobox.cpp
index 3b5a9387ab..abb9262288 100644
--- a/tests/auto/widgets/widgets/qfontcombobox/tst_qfontcombobox.cpp
+++ b/tests/auto/widgets/widgets/qfontcombobox/tst_qfontcombobox.cpp
@@ -1,34 +1,10 @@
-/****************************************************************************
-**
-** 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>
#include <QSignalSpy>
+#include <QFontDatabase>
#include <qfontcombobox.h>
@@ -49,6 +25,7 @@ private slots:
void writingSystem_data();
void writingSystem();
void currentFontChanged();
+ void emptyFont();
};
// Subclass that exposes the protected functions.
@@ -100,7 +77,7 @@ void tst_QFontComboBox::currentFont_data()
if (!QFontDatabase::isPrivateFamily(defaultFont.family()))
QTest::newRow("default2") << defaultFont;
QStringList list = QFontDatabase::families();
- for (int i = 0; i < list.count(); ++i) {
+ for (int i = 0; i < list.size(); ++i) {
QFont f = QFont(QStringList{QFontInfo(QFont(list.at(i))).family()});
if (!QFontDatabase::isPrivateFamily(f.families().first()))
QTest::newRow(qPrintable(list.at(i))) << f;
@@ -128,7 +105,7 @@ void tst_QFontComboBox::currentFont()
if (oldCurrentFont != box.currentFont()) {
//the signal may be emit twice if there is a foundry into brackets
- QCOMPARE(spy0.count(),1);
+ QCOMPARE(spy0.size(),1);
}
}
@@ -178,7 +155,7 @@ void tst_QFontComboBox::fontFilters()
if((fontFilters & spacingMask) == spacingMask)
fontFilters &= ~spacingMask;
- for (int i = 0; i < list.count(); ++i) {
+ for (int i = 0; i < list.size(); ++i) {
if (QFontDatabase::isPrivateFamily(list[i]))
continue;
if (fontFilters & QFontComboBox::ScalableFonts) {
@@ -203,7 +180,7 @@ void tst_QFontComboBox::fontFilters()
if (c == 0)
QCOMPARE(box.currentFont(), QFont());
- QCOMPARE(spy0.count(), (currentFont != box.currentFont()) ? 1 : 0);
+ QCOMPARE(spy0.size(), (currentFont != box.currentFont()) ? 1 : 0);
}
// public QSize sizeHint() const
@@ -244,36 +221,69 @@ void tst_QFontComboBox::writingSystem()
QCOMPARE(box.writingSystem(), writingSystem);
QStringList list = QFontDatabase::families(writingSystem);
- int c = list.count();
- for (int i = 0; i < list.count(); ++i) {
+ int c = list.size();
+ for (int i = 0; i < list.size(); ++i) {
if (QFontDatabase::isPrivateFamily(list[i]))
c--;
}
QCOMPARE(box.model()->rowCount(), c);
- if (list.count() == 0)
+ if (list.size() == 0)
QCOMPARE(box.currentFont(), QFont());
- QCOMPARE(spy0.count(), (currentFont != box.currentFont()) ? 1 : 0);
+ QCOMPARE(spy0.size(), (currentFont != box.currentFont()) ? 1 : 0);
}
// protected void currentFontChanged(QFont const& f)
void tst_QFontComboBox::currentFontChanged()
{
- SubQFontComboBox box;
- QSignalSpy spy0(&box, SIGNAL(currentFontChanged(QFont)));
+ // The absence of this file does not affect the test results
+ QFontDatabase::addApplicationFont("ArianaVioleta-dz2K.ttf");
- if (box.model()->rowCount() > 2) {
- QTest::keyPress(&box, Qt::Key_Down);
- QCOMPARE(spy0.count(), 1);
+ SubQFontComboBox *box = new SubQFontComboBox;
+ QSignalSpy spy0(box, SIGNAL(currentFontChanged(QFont)));
+
+ if (box->model()->rowCount() > 2) {
+ QTest::keyPress(box, Qt::Key_Down);
+ QCOMPARE(spy0.size(), 1);
QFont f( "Sans Serif" );
- box.setCurrentFont(f);
- QCOMPARE(spy0.count(), 2);
+ box->setCurrentFont(f);
+ QCOMPARE(spy0.size(), 2);
} else
qWarning("Not enough fonts installed on test system. Consider adding some");
}
+void tst_QFontComboBox::emptyFont()
+{
+ QFontComboBox fontCB;
+ if (fontCB.count() < 2)
+ QSKIP("Not enough fonts on system to run test.");
+
+ QFont font;
+ font.setFamilies(QStringList());
+
+ // Due to QTBUG-98341, we need to find an index in the family list
+ // which does not match the default index for the empty font, otherwise
+ // the font selection will not be properly updated.
+ {
+ QFontInfo fi(font);
+ QStringList families = QFontDatabase::families();
+ int index = families.indexOf(fi.family());
+ if (index < 0)
+ index = 0;
+ if (index > 0)
+ index--;
+ else
+ index++;
+
+ fontCB.setCurrentIndex(index);
+ }
+
+ fontCB.setCurrentFont(font);
+ QVERIFY(!fontCB.currentFont().families().isEmpty());
+}
+
QTEST_MAIN(tst_QFontComboBox)
#include "tst_qfontcombobox.moc"
diff --git a/tests/auto/widgets/widgets/qframe/BLACKLIST b/tests/auto/widgets/widgets/qframe/BLACKLIST
deleted file mode 100644
index 3a28dd1239..0000000000
--- a/tests/auto/widgets/widgets/qframe/BLACKLIST
+++ /dev/null
@@ -1,3 +0,0 @@
-# QTBUG-69064
-[testPainting]
-android
diff --git a/tests/auto/widgets/widgets/qframe/CMakeLists.txt b/tests/auto/widgets/widgets/qframe/CMakeLists.txt
index 968f9ac3f3..2213f4a7d9 100644
--- a/tests/auto/widgets/widgets/qframe/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qframe/CMakeLists.txt
@@ -1,9 +1,16 @@
-# Generated from qframe.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qframe Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qframe LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
file(GLOB_RECURSE test_data_glob
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -11,10 +18,10 @@ file(GLOB_RECURSE test_data_glob
list(APPEND test_data ${test_data_glob})
qt_internal_add_test(tst_qframe
- LOWDPI # special case
+ LOWDPI
SOURCES
tst_qframe.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
TESTDATA ${test_data}
diff --git a/tests/auto/widgets/widgets/qframe/tst_qframe.cpp b/tests/auto/widgets/widgets/qframe/tst_qframe.cpp
index b5272f6b1a..324c512219 100644
--- a/tests/auto/widgets/widgets/qframe/tst_qframe.cpp
+++ b/tests/auto/widgets/widgets/qframe/tst_qframe.cpp
@@ -1,31 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
-** 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.
+// Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
#include <QFrame>
@@ -173,7 +148,16 @@ void tst_QFrame::testPainting()
frame.setMidLineWidth(midLineWidth);
frame.resize(16, 16);
- const QPixmap pixmap = frame.grab();
+ QPixmap pixmap = frame.grab();
+#ifdef Q_OS_ANDROID
+ // QPixmap is created with system's default format, which is
+ // ARGB32_Premultiplied for Android. For desktop systems the format is
+ // RGB32, so that's also the format of the images in resources. So on
+ // Android we need to explicitly convert the pixmap to a proper format.
+ QImage img = pixmap.toImage();
+ QVERIFY(img.reinterpretAsFormat(QImage::Format_RGB32));
+ pixmap = QPixmap::fromImage(img);
+#endif
const QString fileName = QLatin1String("images/") + basename + QLatin1Char('_')
+ QString::number(lineWidth) + QLatin1Char('_') + QString::number(midLineWidth)
diff --git a/tests/auto/widgets/widgets/qgroupbox/CMakeLists.txt b/tests/auto/widgets/widgets/qgroupbox/CMakeLists.txt
index ed08cce5f2..0414ce0cf5 100644
--- a/tests/auto/widgets/widgets/qgroupbox/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qgroupbox/CMakeLists.txt
@@ -1,13 +1,22 @@
-# Generated from qgroupbox.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qgroupbox Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qgroupbox LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qgroupbox
SOURCES
tst_qgroupbox.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
+ Qt::GuiPrivate
Qt::Widgets
+ Qt::WidgetsPrivate
)
diff --git a/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp b/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp
index b9def66f7c..0d716cce97 100644
--- a/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp
+++ b/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.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>
@@ -36,6 +11,11 @@
#include <QDialog>
#include <QSignalSpy>
+#include <private/qguiapplication_p.h>
+#include <qpa/qplatformtheme.h>
+
+#include <QtWidgets/private/qapplication_p.h>
+
#include "qgroupbox.h"
class tst_QGroupBox : public QObject
@@ -70,6 +50,7 @@ private slots:
void propagateFocus();
void task_QTBUG_19170_ignoreMouseReleaseEvent();
void task_QTBUG_15519_propagateMouseEvents();
+ void buttonPressKeys();
private:
bool checked;
@@ -392,8 +373,8 @@ void tst_QGroupBox::clicked()
else
QTest::mouseClick(&testWidget, Qt::LeftButton);
- QTEST(int(spy.count()), "clickedCount");
- if (spy.count() > 0)
+ QTEST(int(spy.size()), "clickedCount");
+ if (spy.size() > 0)
QTEST(spy.at(0).at(0).toBool(), "finalCheck");
QTEST(testWidget.isChecked(), "finalCheck");
}
@@ -407,9 +388,9 @@ void tst_QGroupBox::toggledVsClicked()
QSignalSpy clickSpy(&groupBox, SIGNAL(clicked(bool)));
groupBox.setChecked(!groupBox.isChecked());
- QCOMPARE(clickSpy.count(), 0);
- QCOMPARE(toggleSpy.count(), 1);
- if (toggleSpy.count() > 0)
+ QCOMPARE(clickSpy.size(), 0);
+ QCOMPARE(toggleSpy.size(), 1);
+ if (toggleSpy.size() > 0)
QCOMPARE(toggleSpy.at(0).at(0).toBool(), groupBox.isChecked());
connect(&groupBox, SIGNAL(clicked(bool)), this, SLOT(clickTimestampSlot()));
@@ -422,8 +403,8 @@ void tst_QGroupBox::toggledVsClicked()
QStyle::SC_GroupBoxCheckBox, &groupBox);
QTest::mouseClick(&groupBox, Qt::LeftButton, {}, rect.center());
- QCOMPARE(clickSpy.count(), 1);
- QCOMPARE(toggleSpy.count(), 2);
+ QCOMPARE(clickSpy.size(), 1);
+ QCOMPARE(toggleSpy.size(), 2);
QVERIFY(toggleTimeStamp < clickTimeStamp);
}
@@ -449,7 +430,7 @@ void tst_QGroupBox::childrenAreDisabled()
layout->addWidget(new QRadioButton);
box.setLayout(layout);
- foreach (QObject *object, box.children()) {
+ for (QObject *object : box.children()) {
if (QWidget *widget = qobject_cast<QWidget *>(object)) {
QVERIFY(!widget->isEnabled());
QVERIFY(!widget->testAttribute(Qt::WA_ForceDisabled));
@@ -457,7 +438,7 @@ void tst_QGroupBox::childrenAreDisabled()
}
box.setChecked(true);
- foreach (QObject *object, box.children()) {
+ for (QObject *object : box.children()) {
if (QWidget *widget = qobject_cast<QWidget *>(object)) {
QVERIFY(widget->isEnabled());
QVERIFY(!widget->testAttribute(Qt::WA_ForceDisabled));
@@ -465,7 +446,7 @@ void tst_QGroupBox::childrenAreDisabled()
}
box.setChecked(false);
- foreach (QObject *object, box.children()) {
+ for (QObject *object : box.children()) {
if (QWidget *widget = qobject_cast<QWidget *>(object)) {
QVERIFY(!widget->isEnabled());
QVERIFY(!widget->testAttribute(Qt::WA_ForceDisabled));
@@ -481,7 +462,7 @@ void tst_QGroupBox::propagateFocus()
QGroupBox box;
QLineEdit lineEdit(&box);
box.show();
- QApplication::setActiveWindow(&box);
+ QApplicationPrivate::setActiveWindow(&box);
QVERIFY(QTest::qWaitForWindowActive(&box));
box.setFocus();
QTRY_COMPARE(qApp->focusWidget(), static_cast<QWidget*>(&lineEdit));
@@ -611,10 +592,25 @@ void tst_QGroupBox::task_QTBUG_15519_propagateMouseEvents()
QCOMPARE(parent.mouseMoved, true);
}
+void tst_QGroupBox::buttonPressKeys()
+{
+ QGroupBox groupBox;
+ groupBox.setCheckable(true);
+ QSignalSpy clickedSpy(&groupBox, &QGroupBox::clicked);
+ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
+ ->themeHint(QPlatformTheme::ButtonPressKeys)
+ .value<QList<Qt::Key>>();
+ for (int i = 0; i < buttonPressKeys.size(); ++i) {
+ QTest::keyClick(&groupBox, buttonPressKeys[i]);
+ QCOMPARE(clickedSpy.size(), i + 1);
+ }
+}
+
void tst_QGroupBox::sendMouseMoveEvent(QWidget *widget, const QPoint &localPos)
{
// Send a MouseMove event without actually moving the pointer
- QMouseEvent event(QEvent::MouseMove, localPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
+ QMouseEvent event(QEvent::MouseMove, localPos, widget->mapToGlobal(localPos),
+ Qt::NoButton, Qt::NoButton, Qt::NoModifier);
QApplication::sendEvent(widget, &event);
}
diff --git a/tests/auto/widgets/widgets/qkeysequenceedit/CMakeLists.txt b/tests/auto/widgets/widgets/qkeysequenceedit/CMakeLists.txt
index a016280b5d..0cf0b1bdd3 100644
--- a/tests/auto/widgets/widgets/qkeysequenceedit/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qkeysequenceedit/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qkeysequenceedit.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qkeysequenceedit Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qkeysequenceedit LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qkeysequenceedit
SOURCES
tst_qkeysequenceedit.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
)
diff --git a/tests/auto/widgets/widgets/qkeysequenceedit/tst_qkeysequenceedit.cpp b/tests/auto/widgets/widgets/qkeysequenceedit/tst_qkeysequenceedit.cpp
index 1a0532ffa4..301be319bf 100644
--- a/tests/auto/widgets/widgets/qkeysequenceedit/tst_qkeysequenceedit.cpp
+++ b/tests/auto/widgets/widgets/qkeysequenceedit/tst_qkeysequenceedit.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>
@@ -45,6 +20,9 @@ private slots:
void testKeys_data();
void testKeys();
void testLineEditContents();
+ void testMaximumSequenceLength();
+ void testFinishingKeyCombinations_data();
+ void testFinishingKeyCombinations();
};
void tst_QKeySequenceEdit::testSetters()
@@ -59,7 +37,7 @@ void tst_QKeySequenceEdit::testSetters()
edit.clear();
QCOMPARE(edit.keySequence(), QKeySequence());
- QCOMPARE(spy.count(), 2);
+ QCOMPARE(spy.size(), 2);
}
void tst_QKeySequenceEdit::testKeys_data()
@@ -74,6 +52,42 @@ void tst_QKeySequenceEdit::testKeys_data()
QTest::newRow("4") << Qt::Key_N << Qt::KeyboardModifiers(Qt::ControlModifier | Qt::ShiftModifier) << QKeySequence("Ctrl+Shift+N");
}
+void tst_QKeySequenceEdit::testMaximumSequenceLength()
+{
+ //
+ // GIVEN:
+ // - A QKeySequenceEdit with maxKeyCount == 1
+ // - A QKeySequence with more than one key
+ //
+ QKeySequenceEdit edit;
+ edit.setMaximumSequenceLength(1);
+ QCOMPARE(edit.maximumSequenceLength(), 1);
+
+ QKeySequence multi("Ctrl+X, S");
+ QCOMPARE(multi.count(), 2);
+
+ //
+ // WHEN: setting the key sequence on the edit
+ //
+ QTest::ignoreMessage(QtWarningMsg,
+ "QKeySequenceEdit: setting a key sequence of length 2 when "
+ "maximumSequenceLength is 1, truncating.");
+ edit.setKeySequence(multi);
+
+ //
+ // THEN:
+ // - the maxKeyCount property doesn't change
+ // - the key sequence is truncated to maxKeyCount
+ // - and won't un-truncate by increasing maxKeyCount
+ //
+ QCOMPARE(edit.maximumSequenceLength(), 1);
+ const auto edited = edit.keySequence();
+ QCOMPARE(edited.count(), 1);
+ QCOMPARE(edited, QKeySequence("Ctrl+X"));
+ edit.setMaximumSequenceLength(2);
+ QCOMPARE(edit.keySequence(), edited);
+}
+
void tst_QKeySequenceEdit::testKeys()
{
QFETCH(Qt::Key, key);
@@ -85,9 +99,9 @@ void tst_QKeySequenceEdit::testKeys()
QTest::keyPress(&edit, key, modifiers);
QTest::keyRelease(&edit, key, modifiers);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
QCOMPARE(edit.keySequence(), keySequence);
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
}
void tst_QKeySequenceEdit::testLineEditContents()
@@ -111,5 +125,43 @@ void tst_QKeySequenceEdit::testLineEditContents()
QCOMPARE(le->text(), QString());
}
+void tst_QKeySequenceEdit::testFinishingKeyCombinations_data()
+{
+ QTest::addColumn<Qt::Key>("key");
+ QTest::addColumn<Qt::KeyboardModifiers>("modifiers");
+ QTest::addColumn<QKeySequence>("keySequence");
+
+ QTest::newRow("1") << Qt::Key_Backtab << Qt::KeyboardModifiers(Qt::NoModifier) << QKeySequence("Backtab");
+ QTest::newRow("2") << Qt::Key_Tab << Qt::KeyboardModifiers(Qt::NoModifier) << QKeySequence("Tab");
+ QTest::newRow("3") << Qt::Key_Return << Qt::KeyboardModifiers(Qt::NoModifier) << QKeySequence("Return");
+ QTest::newRow("4") << Qt::Key_Enter << Qt::KeyboardModifiers(Qt::NoModifier) << QKeySequence("Enter");
+ QTest::newRow("5") << Qt::Key_Enter << Qt::KeyboardModifiers(Qt::ShiftModifier) << QKeySequence("Shift+Enter");
+}
+
+void tst_QKeySequenceEdit::testFinishingKeyCombinations()
+{
+ QFETCH(Qt::Key, key);
+ QFETCH(Qt::KeyboardModifiers, modifiers);
+ QFETCH(QKeySequence, keySequence);
+ QKeySequenceEdit edit;
+
+ QSignalSpy spy(&edit, SIGNAL(editingFinished()));
+ QCOMPARE(spy.size(), 0);
+
+ edit.setFinishingKeyCombinations({QKeyCombination(modifiers, key)});
+ QTest::keyPress(&edit, key, modifiers);
+ QTest::keyRelease(&edit, key, modifiers);
+
+ QCOMPARE(edit.keySequence(), QKeySequence());
+ QTRY_COMPARE(spy.size(), 1);
+
+ edit.setFinishingKeyCombinations({});
+ QTest::keyPress(&edit, key, modifiers);
+ QTest::keyRelease(&edit, key, modifiers);
+
+ QCOMPARE(edit.keySequence(), keySequence);
+ QTRY_COMPARE(spy.size(), 2);
+}
+
QTEST_MAIN(tst_QKeySequenceEdit)
#include "tst_qkeysequenceedit.moc"
diff --git a/tests/auto/widgets/widgets/qlabel/CMakeLists.txt b/tests/auto/widgets/widgets/qlabel/CMakeLists.txt
index bbd51a206c..e29000a6ca 100644
--- a/tests/auto/widgets/widgets/qlabel/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qlabel/CMakeLists.txt
@@ -1,9 +1,16 @@
-# Generated from qlabel.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qlabel Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qlabel LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
file(GLOB_RECURSE test_data_glob
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -17,7 +24,7 @@ list(APPEND test_data ${test_data_glob})
qt_internal_add_test(tst_qlabel
SOURCES
tst_qlabel.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::Gui
Qt::GuiPrivate
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/acc_01/res_Windows_data0.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/acc_01/res_Windows_data0.qsnap
deleted file mode 100644
index 522c173ac4..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/acc_01/res_Windows_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/acc_01/res_Windows_win32_data0.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/acc_01/res_Windows_win32_data0.qsnap
deleted file mode 100644
index acd881d29a..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/acc_01/res_Windows_win32_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data0.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data0.qsnap
deleted file mode 100644
index 9e2c1764d3..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data1.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data1.qsnap
deleted file mode 100644
index dcd708fdbf..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data1.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data10.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data10.qsnap
deleted file mode 100644
index 2131f59fe9..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data10.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data2.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data2.qsnap
deleted file mode 100644
index 2edd976830..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data2.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data3.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data3.qsnap
deleted file mode 100644
index 2ce28d9816..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data3.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data4.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data4.qsnap
deleted file mode 100644
index 6476f6c26b..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data4.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data5.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data5.qsnap
deleted file mode 100644
index 6039742962..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data5.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data6.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data6.qsnap
deleted file mode 100644
index 477d203960..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data6.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data7.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data7.qsnap
deleted file mode 100644
index c673f4099e..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data7.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data8.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data8.qsnap
deleted file mode 100644
index a490f77118..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data8.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data9.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data9.qsnap
deleted file mode 100644
index 33342d3616..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data9.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data0.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data0.qsnap
deleted file mode 100644
index 3fe9a82c2f..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data1.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data1.qsnap
deleted file mode 100644
index 175235dc38..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data1.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data10.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data10.qsnap
deleted file mode 100644
index b1ac74b531..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data10.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data2.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data2.qsnap
deleted file mode 100644
index fdd3c7c701..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data2.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data3.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data3.qsnap
deleted file mode 100644
index caa47f7292..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data3.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data4.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data4.qsnap
deleted file mode 100644
index a0d2498e76..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data4.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data5.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data5.qsnap
deleted file mode 100644
index 756d9fe827..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data5.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data6.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data6.qsnap
deleted file mode 100644
index f973d14c38..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data6.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data7.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data7.qsnap
deleted file mode 100644
index 720d807db2..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data7.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data8.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data8.qsnap
deleted file mode 100644
index 20fd48e7cc..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data8.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data9.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data9.qsnap
deleted file mode 100644
index 7db7c97a14..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data9.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data0.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data0.qsnap
deleted file mode 100644
index d9912d8c92..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data1.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data1.qsnap
deleted file mode 100644
index bfc3a6488e..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data1.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data10.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data10.qsnap
deleted file mode 100644
index 09a35ef761..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data10.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data2.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data2.qsnap
deleted file mode 100644
index 14e11232f0..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data2.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data3.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data3.qsnap
deleted file mode 100644
index 6ef864e635..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data3.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data4.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data4.qsnap
deleted file mode 100644
index eb029008e3..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data4.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data5.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data5.qsnap
deleted file mode 100644
index 439e196b57..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data5.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data6.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data6.qsnap
deleted file mode 100644
index 9637d1741a..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data6.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data7.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data7.qsnap
deleted file mode 100644
index 9a553465c3..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data7.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data8.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data8.qsnap
deleted file mode 100644
index 0d9184c316..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data8.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data9.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data9.qsnap
deleted file mode 100644
index f2873b1c78..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data9.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Motif_data0.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Motif_data0.qsnap
deleted file mode 100644
index 1385a50d38..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Motif_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Motif_data1.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Motif_data1.qsnap
deleted file mode 100644
index 38223cfba2..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Motif_data1.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Motif_data2.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Motif_data2.qsnap
deleted file mode 100644
index 0b946a4968..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Motif_data2.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_data0.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_data0.qsnap
deleted file mode 100644
index e1d2c41d88..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_data1.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_data1.qsnap
deleted file mode 100644
index b7bdee551b..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_data1.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_data2.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_data2.qsnap
deleted file mode 100644
index a20492ee70..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_data2.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_win32_data0.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_win32_data0.qsnap
deleted file mode 100644
index 85e3306d0c..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_win32_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_win32_data1.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_win32_data1.qsnap
deleted file mode 100644
index 3bf991f674..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_win32_data1.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_win32_data2.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_win32_data2.qsnap
deleted file mode 100644
index f05a9dcebd..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_win32_data2.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/Vpix_Motif_data0.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/Vpix_Motif_data0.qsnap
deleted file mode 100644
index d7428df5ef..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/Vpix_Motif_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/Vpix_Windows_data0.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/Vpix_Windows_data0.qsnap
deleted file mode 100644
index 905acd1283..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/Vpix_Windows_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/Vpix_Windows_win32_data0.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/Vpix_Windows_win32_data0.qsnap
deleted file mode 100644
index e1dea4b76b..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/Vpix_Windows_win32_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/empty_Motif_data0.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/empty_Motif_data0.qsnap
deleted file mode 100644
index 055ccda47e..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/empty_Motif_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/empty_Windows_data0.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/empty_Windows_data0.qsnap
deleted file mode 100644
index 64b70763d4..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/empty_Windows_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/empty_Windows_win32_data0.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/empty_Windows_win32_data0.qsnap
deleted file mode 100644
index fb0ea227ad..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/empty_Windows_win32_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/scaledVpix_Motif_data0.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/scaledVpix_Motif_data0.qsnap
deleted file mode 100644
index ae9cda541f..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/scaledVpix_Motif_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/scaledVpix_Windows_data0.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/scaledVpix_Windows_data0.qsnap
deleted file mode 100644
index e21af3223a..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/scaledVpix_Windows_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/scaledVpix_Windows_win32_data0.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/scaledVpix_Windows_win32_data0.qsnap
deleted file mode 100644
index 32cc40652b..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setPixmap/scaledVpix_Windows_win32_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Motif_data0.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Motif_data0.qsnap
deleted file mode 100644
index 7191b517d2..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Motif_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Motif_data1.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Motif_data1.qsnap
deleted file mode 100644
index d943ce960a..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Motif_data1.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Motif_data2.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Motif_data2.qsnap
deleted file mode 100644
index 946432e66d..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Motif_data2.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Motif_data3.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Motif_data3.qsnap
deleted file mode 100644
index dc5ac0c56d..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Motif_data3.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_data0.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_data0.qsnap
deleted file mode 100644
index 2ab392e50e..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_data1.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_data1.qsnap
deleted file mode 100644
index 5769459ab6..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_data1.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_data2.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_data2.qsnap
deleted file mode 100644
index b4206c2a57..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_data2.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_data3.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_data3.qsnap
deleted file mode 100644
index f120ac2e76..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_data3.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_win32_data0.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_win32_data0.qsnap
deleted file mode 100644
index 7644f53726..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_win32_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_win32_data1.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_win32_data1.qsnap
deleted file mode 100644
index 7902b1b087..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_win32_data1.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_win32_data2.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_win32_data2.qsnap
deleted file mode 100644
index 60bd075c78..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_win32_data2.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_win32_data3.qsnap b/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_win32_data3.qsnap
deleted file mode 100644
index c1dcb272b3..0000000000
--- a/tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_win32_data3.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp b/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp
index ad4f8e04bc..325e188091 100644
--- a/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp
+++ b/tests/auto/widgets/widgets/qlabel/tst_qlabel.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,10 +13,13 @@
#include <qmovie.h>
#include <qpicture.h>
#include <qmessagebox.h>
+#include <qsizepolicy.h>
#include <qfontmetrics.h>
#include <qmath.h>
#include <private/qlabel_p.h>
+#include <QtWidgets/private/qapplication_p.h>
+
class Widget : public QWidget
{
Q_OBJECT
@@ -75,6 +53,7 @@ private Q_SLOTS:
#endif
void setNum();
void clear();
+ void wordWrap_data();
void wordWrap();
void eventPropagation_data();
void eventPropagation();
@@ -98,12 +77,16 @@ private Q_SLOTS:
#ifndef QT_NO_CONTEXTMENU
void taskQTBUG_7902_contextMenuCrash();
+ void contextMenu_data();
+ void contextMenu();
#endif
void taskQTBUG_48157_dprPixmap();
void taskQTBUG_48157_dprMovie();
void resourceProvider();
+ void mouseEventPropagation_data();
+ void mouseEventPropagation();
private:
QLabel *testWidget;
@@ -115,16 +98,12 @@ private:
void tst_QLabel::getSetCheck()
{
QLabel obj1;
- // bool QLabel::wordWrap()
- // void QLabel::setWordWrap(bool)
obj1.setWordWrap(false);
- QCOMPARE(false, obj1.wordWrap());
+ QVERIFY(!obj1.wordWrap());
obj1.setWordWrap(true);
- QCOMPARE(true, obj1.wordWrap());
+ QVERIFY(obj1.wordWrap());
#if QT_CONFIG(shortcut)
- // QWidget * QLabel::buddy()
- // void QLabel::setBuddy(QWidget *)
QWidget *var2 = new QWidget();
obj1.setBuddy(var2);
QCOMPARE(var2, obj1.buddy());
@@ -133,8 +112,6 @@ void tst_QLabel::getSetCheck()
delete var2;
#endif // QT_CONFIG(shortcut)
- // QMovie * QLabel::movie()
- // void QLabel::setMovie(QMovie *)
QMovie *var3 = new QMovie;
obj1.setMovie(var3);
QCOMPARE(var3, obj1.movie());
@@ -194,7 +171,7 @@ void tst_QLabel::setBuddy()
layout->addWidget(test_edit);
layout->addWidget(test_edit2);
test_box->show();
- qApp->setActiveWindow(test_box);
+ QApplicationPrivate::setActiveWindow(test_box);
QVERIFY(test_box->isActiveWindow());
test_label->setBuddy( test_edit );
@@ -274,21 +251,36 @@ void tst_QLabel::clear()
QVERIFY(testWidget->text().isEmpty());
}
+void tst_QLabel::wordWrap_data()
+{
+ QTest::addColumn<QString>("text");
+
+ QTest::newRow("Plain text") << "Plain text1";
+ QTest::newRow("Rich text") << "<b>Rich text</b>";
+ QTest::newRow("Long text")
+ << "This is a very long text to check that QLabel "
+ "does not wrap, even if the text would require wrapping to be fully displayed";
+}
+
void tst_QLabel::wordWrap()
{
- QLabel label;
+ QFETCH(QString, text);
+ QLabel label;
+ label.setText(text);
QVERIFY(!label.wordWrap());
+ QVERIFY(!label.sizePolicy().hasHeightForWidth());
- label.setText("Plain Text");
- QVERIFY(!label.wordWrap());
+ const QSize unWrappedSizeHint = label.sizeHint();
- label.setText("<b>rich text</b>");
- QVERIFY(!label.wordWrap());
+ label.setWordWrap(true);
+ QVERIFY(label.sizePolicy().hasHeightForWidth());
+
+ if (text.size() > 1 && text.contains(" ")) {
+ const int wrappedHeight = label.heightForWidth(unWrappedSizeHint.width() / 2);
+ QVERIFY(wrappedHeight > unWrappedSizeHint.height());
+ }
- label.setWordWrap(false);
- label.setText("<b>rich text</b>");
- QVERIFY(!label.wordWrap());
}
void tst_QLabel::eventPropagation_data()
@@ -439,7 +431,6 @@ void tst_QLabel::emptyPixmap()
void tst_QLabel::unicodeText_data()
{
QTest::addColumn<QString>("text");
- QTest::addColumn<QString>("languageName");
/*
The "glass" phrase in Thai was the initial report for bug QTBUG-4848, was
@@ -456,25 +447,21 @@ void tst_QLabel::unicodeText_data()
speech, also translated using http://translate.google.com.
*/
- QTest::newRow("english") << QString::fromUtf8("I can eat glass and it doesn't hurt me.") << QString("english");
- QTest::newRow("thai") << QString::fromUtf8("ฉันจะกินแก้วและไม่เจ็บฉัน") << QString("thai");
- QTest::newRow("chinese") << QString::fromUtf8("我可以吃玻璃,并没有伤害我。") << QString("chinese");
- QTest::newRow("arabic") << QString::fromUtf8("أستطيع أكل الزجاج ، وأنه لا يؤذيني.") << QString("arabic");
- QTest::newRow("russian") << QString::fromUtf8("Я могу есть стекло, и не больно.") << QString("russian");
- QTest::newRow("korean") << QString::fromUtf8("유리를 먹을 수있는, 그리고 그게 날 다치게하지 않습니다.") << QString("korean");
- QTest::newRow("greek") << QString::fromUtf8("Μπορώ να φάτε γυαλί και δεν μου κάνει κακό.") << QString("greek");
- QTest::newRow("german") << QString::fromUtf8("Ich kann Glas essen und es macht mich nicht heiß.") << QString("german");
-
+ QTest::newRow("english") << QString::fromUtf8("I can eat glass and it doesn't hurt me.");
+ QTest::newRow("thai") << QString::fromUtf8("ฉันจะกินแก้วและไม่เจ็บฉัน");
+ QTest::newRow("chinese") << QString::fromUtf8("我可以吃玻璃,并没有伤害我。");
+ QTest::newRow("arabic") << QString::fromUtf8("أستطيع أكل الزجاج ، وأنه لا يؤذيني.");
+ QTest::newRow("russian") << QString::fromUtf8("Я могу есть стекло, и не больно.");
+ QTest::newRow("korean") << QString::fromUtf8("유리를 먹을 수있는, 그리고 그게 날 다치게하지 않습니다.");
+ QTest::newRow("greek") << QString::fromUtf8("Μπορώ να φάτε γυαλί και δεν μου κάνει κακό.");
+ QTest::newRow("german") << QString::fromUtf8("Ich kann Glas essen und es macht mich nicht heiß.");
QTest::newRow("thai_long") << QString::fromUtf8("เราจะต่อสู้ในทะเลและมหาสมุทร. เราจะต่อสู้ด้วยความมั่นใจเติบโตและความเจริญเติบโตในอากาศเราจะปกป้องเกาะของเราค่าใช้จ่ายใดๆอาจ."
- "เราจะต่อสู้บนชายหาดเราจะต่อสู้ในบริเวณเชื่อมโยงไปถึงเราจะต่อสู้ในช่องและในถนนที่เราจะต่อสู้ในภูเขานั้นเราจะไม่ยอม.")
- << QString("thai_long");
+ "เราจะต่อสู้บนชายหาดเราจะต่อสู้ในบริเวณเชื่อมโยงไปถึงเราจะต่อสู้ในช่องและในถนนที่เราจะต่อสู้ในภูเขานั้นเราจะไม่ยอม.");
}
void tst_QLabel::unicodeText()
{
- const QString testDataPath("testdata/unicodeText");
QFETCH(QString, text);
- QFETCH(QString, languageName);
QFrame frame;
QVBoxLayout *layout = new QVBoxLayout();
QLabel *label = new QLabel(text, &frame);
@@ -569,12 +556,50 @@ void tst_QLabel::taskQTBUG_7902_contextMenuCrash()
w->connect(&ti, SIGNAL(timeout()), w, SLOT(deleteLater()));
ti.start(300);
- QContextMenuEvent *cme = new QContextMenuEvent(QContextMenuEvent::Mouse, w->rect().center());
+ QContextMenuEvent *cme = new QContextMenuEvent(QContextMenuEvent::Mouse, w->rect().center(),
+ w->mapToGlobal(w->rect().center()));
qApp->postEvent(w, cme);
QTest::qWait(350);
// No crash, it's allright.
}
+
+void tst_QLabel::contextMenu_data()
+{
+ QTest::addColumn<QString>("text");
+ QTest::addColumn<Qt::TextInteractionFlag>("interactionFlags");
+ QTest::addColumn<bool>("showsContextMenu");
+
+ QTest::addRow("Read-only") << "Plain Text"
+ << Qt::NoTextInteraction
+ << false;
+ QTest::addRow("Selectable") << "Plain Text"
+ << Qt::TextEditorInteraction
+ << true;
+ QTest::addRow("Link") << "<a href=\"nowhere\">Rich text with link</a>"
+ << Qt::TextBrowserInteraction
+ << true;
+ QTest::addRow("Rich text") << "<b>Rich text without link</b>"
+ << Qt::TextBrowserInteraction
+ << true;
+}
+
+void tst_QLabel::contextMenu()
+{
+ QFETCH(QString, text);
+ QFETCH(Qt::TextInteractionFlag, interactionFlags);
+ QFETCH(bool, showsContextMenu);
+
+ QLabel label(text);
+ label.setTextInteractionFlags(interactionFlags);
+ label.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&label));
+
+ const QPoint menuPosition = label.rect().center();
+ QContextMenuEvent cme(QContextMenuEvent::Mouse, menuPosition, label.mapToGlobal(menuPosition));
+ QApplication::sendEvent(&label, &cme);
+ QCOMPARE(cme.isAccepted(), showsContextMenu);
+}
#endif
void tst_QLabel::taskQTBUG_48157_dprPixmap()
@@ -616,5 +641,94 @@ void tst_QLabel::resourceProvider()
QVERIFY(providerCalled > 0);
}
+// Test if mouse events are correctly propagated to the parent widget,
+// even if a label contains rich text (QTBUG-110055)
+void tst_QLabel::mouseEventPropagation_data()
+{
+ QTest::addColumn<const QString>("text");
+ QTest::addColumn<const Qt::TextInteractionFlag>("interaction");
+ QTest::addColumn<const QList<Qt::MouseButton>>("buttons");
+ QTest::addColumn<const bool>("expectPropagation");
+
+
+ QTest::newRow("RichText")
+ << QString("<b>This is a rich text propagating mouse events</b>")
+ << Qt::LinksAccessibleByMouse
+ << QList<Qt::MouseButton>{Qt::LeftButton, Qt::RightButton, Qt::MiddleButton}
+ << true;
+ QTest::newRow("PlainText")
+ << QString("This is a plain text propagating mouse events")
+ << Qt::LinksAccessibleByMouse
+ << QList<Qt::MouseButton>{Qt::LeftButton, Qt::RightButton, Qt::MiddleButton}
+ << true;
+ QTest::newRow("PlainTextConsume")
+ << QString("This is a plain text consuming mouse events")
+ << Qt::TextSelectableByMouse
+ << QList<Qt::MouseButton>{Qt::LeftButton}
+ << false;
+ QTest::newRow("RichTextConsume")
+ << QString("<b>This is a rich text consuming mouse events</b>")
+ << Qt::TextSelectableByMouse
+ << QList<Qt::MouseButton>{Qt::LeftButton}
+ << false;
+ QTest::newRow("PlainTextNoInteraction")
+ << QString("This is a text not interacting with mouse")
+ << Qt::NoTextInteraction
+ << QList<Qt::MouseButton>{Qt::LeftButton, Qt::RightButton, Qt::MiddleButton}
+ << true;
+ QTest::newRow("RichTextNoInteraction")
+ << QString("<b>This is a rich text not interacting with mouse</b>")
+ << Qt::NoTextInteraction
+ << QList<Qt::MouseButton>{Qt::LeftButton, Qt::RightButton, Qt::MiddleButton}
+ << true;
+}
+
+void tst_QLabel::mouseEventPropagation()
+{
+ class MouseEventWidget : public QWidget
+ {
+ public:
+ uint pressed() const { return m_pressed; }
+ uint released() const { return m_released; }
+
+ private:
+ uint m_pressed = 0;
+ uint m_released = 0;
+ void mousePressEvent(QMouseEvent *event) override
+ {
+ ++m_pressed;
+ return QWidget::mousePressEvent(event);
+ }
+
+ void mouseReleaseEvent(QMouseEvent *event) override
+ {
+ ++m_released;
+ return QWidget::mouseReleaseEvent(event);
+ }
+ };
+
+ QFETCH(const QString, text);
+ QFETCH(const Qt::TextInteractionFlag, interaction);
+ QFETCH(const QList<Qt::MouseButton>, buttons);
+ QFETCH(const bool, expectPropagation);
+
+ MouseEventWidget widget;
+ auto *layout = new QVBoxLayout(&widget);
+ auto *label = new QLabel(text);
+ label->setTextInteractionFlags(interaction);
+
+ layout->addWidget(label);
+ widget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&widget));
+
+ const QPoint labelCenter = label->rect().center();
+ for (Qt::MouseButton mouseButton : buttons)
+ QTest::mouseClick(label, mouseButton, Qt::KeyboardModifiers(), labelCenter);
+
+ const uint count = expectPropagation ? buttons.count() : 0;
+ QTRY_COMPARE(widget.pressed(), count);
+ QTRY_COMPARE(widget.released(), count);
+}
+
QTEST_MAIN(tst_QLabel)
#include "tst_qlabel.moc"
diff --git a/tests/auto/widgets/widgets/qlcdnumber/CMakeLists.txt b/tests/auto/widgets/widgets/qlcdnumber/CMakeLists.txt
index 4d6a8ff77a..954ec095e5 100644
--- a/tests/auto/widgets/widgets/qlcdnumber/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qlcdnumber/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qlcdnumber.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qlcdnumber Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qlcdnumber LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qlcdnumber
SOURCES
tst_qlcdnumber.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
)
diff --git a/tests/auto/widgets/widgets/qlcdnumber/tst_qlcdnumber.cpp b/tests/auto/widgets/widgets/qlcdnumber/tst_qlcdnumber.cpp
index a97a090ebd..8fcf9c49fe 100644
--- a/tests/auto/widgets/widgets/qlcdnumber/tst_qlcdnumber.cpp
+++ b/tests/auto/widgets/widgets/qlcdnumber/tst_qlcdnumber.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>
diff --git a/tests/auto/widgets/widgets/qlineedit/BLACKLIST b/tests/auto/widgets/widgets/qlineedit/BLACKLIST
index 9f87a6d921..a459495d1a 100644
--- a/tests/auto/widgets/widgets/qlineedit/BLACKLIST
+++ b/tests/auto/widgets/widgets/qlineedit/BLACKLIST
@@ -3,13 +3,7 @@
android
[leftKeyOnSelectedText]
android
-[cutWithoutSelection]
-android
-[inlineCompletion]
-android
[textMargin]
android
-[task210502_caseInsensitiveInlineCompletion]
-android
[testQuickSelectionWithMouse]
android
diff --git a/tests/auto/widgets/widgets/qlineedit/CMakeLists.txt b/tests/auto/widgets/widgets/qlineedit/CMakeLists.txt
index 8cdee2a111..22ecf40aed 100644
--- a/tests/auto/widgets/widgets/qlineedit/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qlineedit/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qlineedit.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qlineedit Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qlineedit LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qlineedit
SOURCES
tst_qlineedit.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::Gui
Qt::GuiPrivate
@@ -20,6 +27,6 @@ qt_internal_add_test(tst_qlineedit
#####################################################################
qt_internal_extend_target(tst_qlineedit CONDITION MACOS
- PUBLIC_LIBRARIES
+ LIBRARIES
${FWAppKit}
)
diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
index d6c6211e01..be185c1e7a 100644
--- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
+++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.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>
@@ -292,6 +267,8 @@ private slots:
void inputMethodQueryImHints_data();
void inputMethodQueryImHints();
+ void inputMethodQueryEnterKeyType();
+
void inputMethodUpdate();
void undoRedoAndEchoModes_data();
@@ -315,6 +292,13 @@ private slots:
void QTBUG_60319_setInputMaskCheckImSurroundingText();
void testQuickSelectionWithMouse();
void inputRejected();
+ void keyReleasePropagates();
+
+#if QT_CONFIG(shortcut)
+ void deleteWordByKeySequence_data();
+ void deleteWordByKeySequence();
+#endif
+
protected slots:
void editingFinished();
@@ -677,7 +661,7 @@ void tst_QLineEdit::setInputMask()
testWidget->insert(input);
} else {
psKeyClick(testWidget, Qt::Key_Home);
- for (int i=0; i<input.length(); i++)
+ for (int i=0; i<input.size(); i++)
QTest::keyClick(testWidget, input.at(i).toLatin1());
}
@@ -944,8 +928,8 @@ void tst_QLineEdit::hasAcceptableInputValidator()
qApp->sendEvent(testWidget, &lostFocus);
QVERIFY(testWidget->hasAcceptableInput());
- QCOMPARE(spyChanged.count(), 2);
- QCOMPARE(spyEdited.count(), 0);
+ QCOMPARE(spyChanged.size(), 2);
+ QCOMPARE(spyEdited.size(), 0);
}
@@ -1617,7 +1601,7 @@ void tst_QLineEdit::setText()
QSignalSpy editedSpy(testWidget, SIGNAL(textEdited(QString)));
QSignalSpy changedSpy(testWidget, SIGNAL(textChanged(QString)));
testWidget->setText("hello");
- QCOMPARE(editedSpy.count(), 0);
+ QCOMPARE(editedSpy.size(), 0);
QCOMPARE(changedSpy.value(0).value(0).toString(), QString("hello"));
}
@@ -1689,7 +1673,7 @@ void tst_QLineEdit::displayText_data()
QString input;
QString pass;
input = "Hello World";
- pass.resize(input.length());
+ pass.resize(input.size());
pass.fill(passChar);
QTest::newRow(QString(s + " text0").toLatin1()) << input << pass << m << bool(use_setText);
QTest::newRow(QString(s + " text1").toLatin1()) << QString("") <<
@@ -1697,14 +1681,14 @@ void tst_QLineEdit::displayText_data()
m << bool(use_setText);
QTest::newRow(QString(s + " text2").toLatin1()) << QString("A") << QString(passChar) << m << bool(use_setText);
input = QString("ryyryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryryrryryryryryryryryryryryryry");
- pass.resize(input.length());
+ pass.resize(input.size());
pass.fill(passChar);
QTest::newRow(QString(s + " text3").toLatin1()) << input << pass << m << bool(use_setText);
input = QString("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890`~!@#$%^&*()_-+={[}]|\\:;'?/>.<,\"");
- pass.fill(passChar, input.length());
+ pass.fill(passChar, input.size());
QTest::newRow(QString(s + " text4").toLatin1()) << input << pass << m << bool(use_setText);
input = QString("Hello") + QChar(0xa0) + "World";
- pass.resize(input.length());
+ pass.resize(input.size());
pass.fill(passChar);
QTest::newRow(QString(s + " text with nbsp").toLatin1()) << input << pass << m << bool(use_setText);
}
@@ -2317,7 +2301,7 @@ void tst_QLineEdit::deleteSelectedText()
#ifndef QT_NO_CONTEXTMENU
QMenu *menu = edit.createStandardContextMenu();
- for (int i = 0; i < menu->actions().count(); ++i) {
+ for (int i = 0; i < menu->actions().size(); ++i) {
QAction *current = menu->actions().at(i);
if (current->text() == QLineEdit::tr("Delete")) {
current->trigger(); //this will delete the whole text selected
@@ -2450,7 +2434,7 @@ class QIntFixValidator : public QIntValidator {
public:
QIntFixValidator(int min, int max, QObject *parent) : QIntValidator(min, max, parent) {}
void fixup (QString &input) const override {
- for (int i=0; i<input.length(); ++i)
+ for (int i=0; i<input.size(); ++i)
if (!input.at(i).isNumber()) {
input[(int)i] = QChar('0');
}
@@ -3016,7 +3000,7 @@ void tst_QLineEdit::setSelection_data()
QTest::newRow(selectionTestName(start, length).constData())
<< text << start << length << pos << QString("Abc ") << true;
- start = -1; length = 0; pos = text.length();
+ start = -1; length = 0; pos = text.size();
QTest::newRow(selectionTestName(start, length).constData())
<< text << start << length << pos << QString() << false;
@@ -3036,7 +3020,7 @@ void tst_QLineEdit::setSelection_data()
QTest::newRow(selectionTestName(start, length).constData())
<< text << start << length << pos << QString("A") << true;
- start = -1; length = -1; pos = text.length();
+ start = -1; length = -1; pos = text.size();
QTest::newRow(selectionTestName(start, length).constData())
<< text << start << length << pos << QString() << false;
}
@@ -3333,7 +3317,7 @@ void tst_QLineEdit::validateOnFocusOut()
QTest::keyPress(testWidget, '0');
QCOMPARE(testWidget->text(), QString("10"));
testWidget->clearFocus();
- QCOMPARE(editingFinishedSpy.count(), 0);
+ QCOMPARE(editingFinishedSpy.size(), 0);
testWidget->setFocus();
centerOnScreen(testWidget);
@@ -3346,7 +3330,7 @@ void tst_QLineEdit::validateOnFocusOut()
QTRY_COMPARE(testWidget->text(), QString("100"));
testWidget->clearFocus();
- QCOMPARE(editingFinishedSpy.count(), 1);
+ QCOMPARE(editingFinishedSpy.size(), 1);
}
void tst_QLineEdit::editInvalidText()
@@ -3430,6 +3414,9 @@ void tst_QLineEdit::leftKeyOnSelectedText()
void tst_QLineEdit::inlineCompletion()
{
+#ifdef Q_OS_ANDROID
+ QSKIP("QCompleter does not work on Android, see QTBUG-77174");
+#endif
if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
QSKIP("Wayland: This fails. Figure out why.");
@@ -3521,7 +3508,7 @@ void tst_QLineEdit::noTextEditedOnClear()
testWidget->setText("Test");
QSignalSpy textEditedSpy(testWidget, SIGNAL(textEdited(QString)));
testWidget->clear();
- QCOMPARE(textEditedSpy.count(), 0);
+ QCOMPARE(textEditedSpy.size(), 0);
}
void tst_QLineEdit::textMargin_data()
@@ -3537,11 +3524,12 @@ void tst_QLineEdit::textMargin_data()
QLineEdit testWidget;
QFontMetrics metrics(testWidget.font());
const QString s = QLatin1String("MMM MMM MMM");
+ const int windows11StyleHorizontalOffset = qApp->style()->inherits("QWindows11Style") ? 8 : 0;
// Different styles generate different offsets, so
// calculate the width rather than hardcode it.
- const int pixelWidthOfM = metrics.horizontalAdvance(s, 1);
- const int pixelWidthOfMMM_MM = metrics.horizontalAdvance(s, 6);
+ const int pixelWidthOfM = windows11StyleHorizontalOffset + metrics.horizontalAdvance(s, 1);
+ const int pixelWidthOfMMM_MM = windows11StyleHorizontalOffset + metrics.horizontalAdvance(s, 6);
QTest::newRow("default-0") << 0 << 0 << 0 << 0 << QPoint(pixelWidthOfMMM_MM, 0) << 6;
QTest::newRow("default-1") << 0 << 0 << 0 << 0 << QPoint(1, 1) << 0;
@@ -3625,7 +3613,7 @@ void tst_QLineEdit::returnKeyClearsEditedFlag()
// Focus drop with no edits shouldn't emit signal, edited flag == false
testWidget.clearFocus(); // Signal not emitted
QVERIFY(!testWidget.hasFocus());
- QCOMPARE(leSpy.count(), 0);
+ QCOMPARE(leSpy.size(), 0);
// Focus drop after edits should emit signal, edited flag == true
testWidget.setFocus();
@@ -3633,7 +3621,7 @@ void tst_QLineEdit::returnKeyClearsEditedFlag()
QTest::keyClicks(&testWidget, "edit1 "); // edited flag set
testWidget.clearFocus(); // edited flag cleared, signal emitted
QVERIFY(!testWidget.hasFocus());
- QCOMPARE(leSpy.count(), 1);
+ QCOMPARE(leSpy.size(), 1);
// Only text related keys should set edited flag
testWidget.setFocus();
@@ -3643,7 +3631,7 @@ void tst_QLineEdit::returnKeyClearsEditedFlag()
QTest::keyClick(&testWidget, Qt::Key_PageUp);
testWidget.clearFocus(); // Signal not emitted
QVERIFY(!testWidget.hasFocus());
- QCOMPARE(leSpy.count(), 1); // No change
+ QCOMPARE(leSpy.size(), 1); // No change
// Return should always emit signal
testWidget.setFocus();
@@ -3651,12 +3639,12 @@ void tst_QLineEdit::returnKeyClearsEditedFlag()
QTest::keyClick(&testWidget, Qt::Key_Return); /* Without edits,
signal emitted,
edited flag cleared */
- QCOMPARE(leSpy.count(), 2);
+ QCOMPARE(leSpy.size(), 2);
QTest::keyClicks(&testWidget, "edit2 "); // edited flag set
QTest::keyClick(&testWidget, Qt::Key_Return); /* With edits,
signal emitted,
edited flag cleared */
- QCOMPARE(leSpy.count(), 3);
+ QCOMPARE(leSpy.size(), 3);
/* After editing the line edit following a Return key press with a
focus drop should not emit signal a second time since Return now
@@ -3664,10 +3652,10 @@ void tst_QLineEdit::returnKeyClearsEditedFlag()
QTest::keyClicks(&testWidget, "edit3 "); // edited flag set
QTest::keyClick(&testWidget, Qt::Key_Return); /* signal emitted,
edited flag cleared */
- QCOMPARE(leSpy.count(), 4);
+ QCOMPARE(leSpy.size(), 4);
testWidget.clearFocus(); // Signal not emitted since edited == false
QVERIFY(!testWidget.hasFocus());
- QCOMPARE(leSpy.count(), 4); // No change
+ QCOMPARE(leSpy.size(), 4); // No change
}
#ifndef QT_NO_CURSOR
@@ -3734,7 +3722,7 @@ void tst_QLineEdit::task174640_editingFinished()
layout->addWidget(le2);
mw.show();
- QApplication::setActiveWindow(&mw);
+ QApplicationPrivate::setActiveWindow(&mw);
mw.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&mw));
QCOMPARE(&mw, QApplication::activeWindow());
@@ -3743,19 +3731,19 @@ void tst_QLineEdit::task174640_editingFinished()
le1->setFocus();
QTRY_VERIFY(le1->hasFocus());
- QCOMPARE(editingFinishedSpy.count(), 0);
+ QCOMPARE(editingFinishedSpy.size(), 0);
le2->setFocus();
QTRY_VERIFY(le2->hasFocus());
// editingFinished will not be emitted anew because no editing happened
- QCOMPARE(editingFinishedSpy.count(), 0);
+ QCOMPARE(editingFinishedSpy.size(), 0);
le1->setFocus();
QTRY_VERIFY(le1->hasFocus());
QTest::keyPress(le1, Qt::Key_Plus);
le2->setFocus();
QTRY_VERIFY(le2->hasFocus());
- QCOMPARE(editingFinishedSpy.count(), 1);
+ QCOMPARE(editingFinishedSpy.size(), 1);
editingFinishedSpy.clear();
le1->setFocus();
@@ -3770,7 +3758,7 @@ void tst_QLineEdit::task174640_editingFinished()
mw.activateWindow();
delete testMenu1;
- QCOMPARE(editingFinishedSpy.count(), 0);
+ QCOMPARE(editingFinishedSpy.size(), 0);
QTRY_VERIFY(le1->hasFocus());
// Ensure le1 has been edited
QTest::keyPress(le1, Qt::Key_Plus);
@@ -3783,7 +3771,7 @@ void tst_QLineEdit::task174640_editingFinished()
QTest::qWait(20);
mw.activateWindow();
delete testMenu2;
- QCOMPARE(editingFinishedSpy.count(), 1);
+ QCOMPARE(editingFinishedSpy.size(), 1);
}
#if QT_CONFIG(completer)
@@ -3827,6 +3815,9 @@ void tst_QLineEdit::task198789_currentCompletion()
void tst_QLineEdit::task210502_caseInsensitiveInlineCompletion()
{
+#ifdef Q_OS_ANDROID
+ QSKIP("QCompleter does not work on Android, see QTBUG-77174");
+#endif
if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
QSKIP("Wayland: This fails. Figure out why.");
@@ -3839,7 +3830,7 @@ void tst_QLineEdit::task210502_caseInsensitiveInlineCompletion()
completer.setCompletionMode(QCompleter::InlineCompletion);
lineEdit.setCompleter(&completer);
lineEdit.show();
- QApplication::setActiveWindow(&lineEdit);
+ QApplicationPrivate::setActiveWindow(&lineEdit);
QVERIFY(QTest::qWaitForWindowActive(&lineEdit));
lineEdit.setFocus();
QTRY_VERIFY(lineEdit.hasFocus());
@@ -3865,7 +3856,7 @@ void tst_QLineEdit::task229938_dontEmitChangedWhenTextIsNotChanged()
QTest::keyPress(&lineEdit, 'd');
QTest::keyPress(&lineEdit, 'e');
QTest::keyPress(&lineEdit, 'f');
- QCOMPARE(changedSpy.count(), 5);
+ QCOMPARE(changedSpy.size(), 5);
}
void tst_QLineEdit::task233101_cursorPosAfterInputMethod_data()
@@ -3940,7 +3931,7 @@ void tst_QLineEdit::task241436_passwordEchoOnEditRestoreEchoMode()
testWidget->setFocus();
centerOnScreen(testWidget);
testWidget->show();
- QApplication::setActiveWindow(testWidget);
+ QApplicationPrivate::setActiveWindow(testWidget);
QVERIFY(QTest::qWaitForWindowActive(testWidget));
QVERIFY(testWidget->hasFocus());
@@ -3991,7 +3982,7 @@ void tst_QLineEdit::taskQTBUG_4401_enterKeyClearsPassword()
testWidget->selectAll();
centerOnScreen(testWidget);
testWidget->show();
- QApplication::setActiveWindow(testWidget);
+ QApplicationPrivate::setActiveWindow(testWidget);
QVERIFY(QTest::qWaitForWindowActive(testWidget));
QTest::keyPress(testWidget, Qt::Key_Enter);
@@ -4047,7 +4038,8 @@ void tst_QLineEdit::taskQTBUG_7902_contextMenuCrash()
w->connect(&ti, SIGNAL(timeout()), w, SLOT(deleteLater()));
ti.start(200);
- QContextMenuEvent *cme = new QContextMenuEvent(QContextMenuEvent::Mouse, w->rect().center());
+ QContextMenuEvent *cme = new QContextMenuEvent(QContextMenuEvent::Mouse, w->rect().center(),
+ w->mapToGlobal(w->rect().center()));
qApp->postEvent(w, cme);
QTest::qWait(300);
@@ -4073,13 +4065,13 @@ void tst_QLineEdit::taskQTBUG_7395_readOnlyShortcut()
le.show();
QVERIFY(QTest::qWaitForWindowExposed(&le));
- QApplication::setActiveWindow(&le);
+ QApplicationPrivate::setActiveWindow(&le);
QVERIFY(QTest::qWaitForWindowActive(&le));
le.setFocus();
QTRY_VERIFY(le.hasFocus());
QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_P);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
}
void tst_QLineEdit::QTBUG697_paletteCurrentColorGroup()
@@ -4095,7 +4087,7 @@ void tst_QLineEdit::QTBUG697_paletteCurrentColorGroup()
le.setPalette(p);
le.show();
- QApplication::setActiveWindow(&le);
+ QApplicationPrivate::setActiveWindow(&le);
QVERIFY(QTest::qWaitForWindowActive(&le));
le.setFocus();
QTRY_VERIFY(le.hasFocus());
@@ -4123,7 +4115,7 @@ void tst_QLineEdit::QTBUG13520_textNotVisible()
QString sometext("01-ST16-01SIL-MPL001wfgsdfgsdgsdfgsdfgsdfgsdfgsdfg");
le.setText(sometext);
le.setCursorPosition(0);
- QTest::qWait(100); //just make sure we get he lineedit correcly painted
+ QTest::qWait(100); //just make sure we get he lineedit correctly painted
auto expectedCursorCoordinate = le.width() - le.fontMetrics().horizontalAdvance(sometext);
// cursor does not leave widget to the left:
@@ -4366,14 +4358,14 @@ void tst_QLineEdit::inputMethodSelection()
testWidget->setSelection(0,0);
QSignalSpy selectionSpy(testWidget, SIGNAL(selectionChanged()));
- QCOMPARE(selectionSpy.count(), 0);
+ QCOMPARE(selectionSpy.size(), 0);
QCOMPARE(testWidget->selectionStart(), -1);
QCOMPARE(testWidget->selectionEnd(), -1);
QCOMPARE(testWidget->selectionLength(), 0);
testWidget->setSelection(0,5);
- QCOMPARE(selectionSpy.count(), 1);
+ QCOMPARE(selectionSpy.size(), 1);
QCOMPARE(testWidget->selectionStart(), 0);
QCOMPARE(testWidget->selectionEnd(), 5);
QCOMPARE(testWidget->selectionLength(), 5);
@@ -4387,7 +4379,7 @@ void tst_QLineEdit::inputMethodSelection()
QApplication::sendEvent(testWidget, &event);
}
- QCOMPARE(selectionSpy.count(), 2);
+ QCOMPARE(selectionSpy.size(), 2);
QCOMPARE(testWidget->selectionStart(), 12);
QCOMPARE(testWidget->selectionEnd(), 17);
QCOMPARE(testWidget->selectionLength(), 5);
@@ -4400,7 +4392,7 @@ void tst_QLineEdit::inputMethodSelection()
QApplication::sendEvent(testWidget, &event);
}
- QCOMPARE(selectionSpy.count(), 3);
+ QCOMPARE(selectionSpy.size(), 3);
QCOMPARE(testWidget->selectionStart(), -1);
QCOMPARE(testWidget->selectionEnd(), -1);
QCOMPARE(testWidget->selectionLength(), 0);
@@ -4427,6 +4419,33 @@ void tst_QLineEdit::inputMethodQueryImHints()
QCOMPARE(static_cast<Qt::InputMethodHints>(value.toInt()), hints);
}
+void tst_QLineEdit::inputMethodQueryEnterKeyType()
+{
+ QWidget mw;
+ QVBoxLayout layout(&mw);
+ QLineEdit le1(&mw);
+ layout.addWidget(&le1);
+ mw.show();
+ QVariant enterType = le1.inputMethodQuery(Qt::ImEnterKeyType);
+ QCOMPARE(enterType.value<Qt::EnterKeyType>(), Qt::EnterKeyDefault);
+
+ mw.hide();
+ QLineEdit le2(&mw);
+ layout.addWidget(&le2);
+ mw.show();
+
+ enterType = le1.inputMethodQuery(Qt::ImEnterKeyType);
+#ifdef Q_OS_ANDROID
+ // QTBUG-61652
+ // EnterKey is changed to EnterKeyNext if the focus can be moved to widget below
+ QCOMPARE(enterType.value<Qt::EnterKeyType>(), Qt::EnterKeyNext);
+#else
+ QCOMPARE(enterType.value<Qt::EnterKeyType>(), Qt::EnterKeyDefault);
+#endif
+ enterType = le2.inputMethodQuery(Qt::ImEnterKeyType);
+ QCOMPARE(enterType.value<Qt::EnterKeyType>(), Qt::EnterKeyDefault);
+}
+
void tst_QLineEdit::inputMethodUpdate()
{
if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
@@ -4563,7 +4582,7 @@ void tst_QLineEdit::clearButton()
l->addWidget(listView);
testWidget.move(300, 300);
testWidget.show();
- qApp->setActiveWindow(&testWidget);
+ QApplicationPrivate::setActiveWindow(&testWidget);
QVERIFY(QTest::qWaitForWindowActive(&testWidget));
// Flip the clear button on,off, trying to detect crashes.
filterLineEdit->setClearButtonEnabled(true);
@@ -4588,11 +4607,11 @@ void tst_QLineEdit::clearButton()
QSignalSpy spyEdited(filterLineEdit, &QLineEdit::textEdited);
const QPoint clearButtonCenterPos = QRect(QPoint(0, 0), clearButton->size()).center();
QTest::mouseClick(clearButton, Qt::LeftButton, {}, clearButtonCenterPos);
- QCOMPARE(spyEdited.count(), 1);
+ QCOMPARE(spyEdited.size(), 1);
QTRY_COMPARE(clearButton->cursor().shape(), filterLineEdit->cursor().shape());
QTRY_COMPARE(filterModel->rowCount(), 3);
QCoreApplication::processEvents();
- QCOMPARE(spyEdited.count(), 1);
+ QCOMPARE(spyEdited.size(), 1);
filterLineEdit->setReadOnly(true); // QTBUG-34315
QVERIFY(!clearButton->isEnabled());
@@ -4674,7 +4693,8 @@ void tst_QLineEdit::sideWidgets()
testWidget.move(300, 300);
testWidget.show();
QVERIFY(QTest::qWaitForWindowExposed(&testWidget));
- foreach (QToolButton *button, lineEdit->findChildren<QToolButton *>())
+ const auto buttons = lineEdit->findChildren<QToolButton *>();
+ for (QToolButton *button : buttons)
QCOMPARE(button->cursor().shape(), Qt::ArrowCursor);
// Arbitrarily add/remove actions, trying to detect crashes. Add QTRY_VERIFY(false) to view the result.
delete label3Action;
@@ -4689,7 +4709,8 @@ void tst_QLineEdit::sideWidgets()
template <class T> T *findAssociatedWidget(const QAction *a)
{
- foreach (QWidget *w, a->associatedWidgets()) {
+ const auto associatedObjects = a->associatedObjects();
+ for (QObject *w : associatedObjects) {
if (T *result = qobject_cast<T *>(w))
return result;
}
@@ -4869,7 +4890,7 @@ void tst_QLineEdit::QTBUG1266_setInputMaskEmittingTextEdited()
QSignalSpy spy(&lineEdit, SIGNAL(textEdited(QString)));
lineEdit.setInputMask("AAAA");
lineEdit.setInputMask(QString());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
}
#if QT_CONFIG(shortcut)
@@ -4930,7 +4951,7 @@ void tst_QLineEdit::shortcutOverrideOnReadonlyLineEdit()
}
const int activationCount = shouldBeHandledByQLineEdit ? 0 : 1;
- QCOMPARE(spy.count(), activationCount);
+ QCOMPARE(spy.size(), activationCount);
}
#endif // QT_CONFIG(shortcut)
@@ -4963,7 +4984,7 @@ void tst_QLineEdit::QTBUG59957_clearButtonLeftmostAction()
bool tst_QLineEdit::unselectingWithLeftOrRightChangesCursorPosition()
{
-#if defined Q_OS_WIN || defined Q_OS_QNX //Windows and QNX do not jump to the beginning of the selection
+#if defined Q_OS_WIN || defined Q_OS_QNX || defined Q_OS_VXWORKS //Windows, QNX and VxWorks do not jump to the beginning of the selection
return true;
#endif
// Platforms minimal/offscreen also need left after unselecting with right
@@ -4983,10 +5004,10 @@ void tst_QLineEdit::QTBUG_60319_setInputMaskCheckImSurroundingText()
QLineEdit *testWidget = ensureTestWidget();
QString mask("+000(000)-000-00-00");
testWidget->setInputMask(mask);
- testWidget->setCursorPosition(mask.length());
+ testWidget->setCursorPosition(mask.size());
QString surroundingText = testWidget->inputMethodQuery(Qt::ImSurroundingText).toString();
int cursorPosition = testWidget->inputMethodQuery(Qt::ImCursorPosition).toInt();
- QCOMPARE(surroundingText.length(), cursorPosition);
+ QCOMPARE(surroundingText.size(), cursorPosition);
}
void tst_QLineEdit::testQuickSelectionWithMouse()
@@ -5083,18 +5104,18 @@ void tst_QLineEdit::inputRejected()
QSignalSpy spyInputRejected(testWidget, SIGNAL(inputRejected()));
QTest::keyClicks(testWidget, "abcde");
- QCOMPARE(spyInputRejected.count(), 0);
+ QCOMPARE(spyInputRejected.size(), 0);
testWidget->setText("fghij");
- QCOMPARE(spyInputRejected.count(), 0);
+ QCOMPARE(spyInputRejected.size(), 0);
testWidget->insert("k");
- QCOMPARE(spyInputRejected.count(), 0);
+ QCOMPARE(spyInputRejected.size(), 0);
testWidget->clear();
testWidget->setMaxLength(5);
QTest::keyClicks(testWidget, "abcde");
- QCOMPARE(spyInputRejected.count(), 0);
+ QCOMPARE(spyInputRejected.size(), 0);
QTest::keyClicks(testWidget, "fgh");
- QCOMPARE(spyInputRejected.count(), 3);
+ QCOMPARE(spyInputRejected.size(), 3);
#if QT_CONFIG(clipboard)
testWidget->clear();
spyInputRejected.clear();
@@ -5102,7 +5123,7 @@ void tst_QLineEdit::inputRejected()
testWidget->paste();
// The first 5 characters are accepted, but
// the last 2 are not.
- QCOMPARE(spyInputRejected.count(), 1);
+ QCOMPARE(spyInputRejected.size(), 1);
#endif
testWidget->setMaxLength(INT_MAX);
@@ -5111,15 +5132,15 @@ void tst_QLineEdit::inputRejected()
QIntValidator intValidator(1, 100);
testWidget->setValidator(&intValidator);
QTest::keyClicks(testWidget, "11");
- QCOMPARE(spyInputRejected.count(), 0);
+ QCOMPARE(spyInputRejected.size(), 0);
QTest::keyClicks(testWidget, "a#");
- QCOMPARE(spyInputRejected.count(), 2);
+ QCOMPARE(spyInputRejected.size(), 2);
#if QT_CONFIG(clipboard)
testWidget->clear();
spyInputRejected.clear();
QApplication::clipboard()->setText("a#");
testWidget->paste();
- QCOMPARE(spyInputRejected.count(), 1);
+ QCOMPARE(spyInputRejected.size(), 1);
#endif
testWidget->clear();
@@ -5127,10 +5148,154 @@ void tst_QLineEdit::inputRejected()
spyInputRejected.clear();
testWidget->setInputMask("999.999.999.999;_");
QTest::keyClicks(testWidget, "11");
- QCOMPARE(spyInputRejected.count(), 0);
+ QCOMPARE(spyInputRejected.size(), 0);
QTest::keyClicks(testWidget, "a#");
- QCOMPARE(spyInputRejected.count(), 2);
+ QCOMPARE(spyInputRejected.size(), 2);
}
+void tst_QLineEdit::keyReleasePropagates()
+{
+ struct Dialog : QWidget
+ {
+ QLineEdit *lineEdit;
+ int releasedKey = {};
+
+ Dialog()
+ {
+ lineEdit = new QLineEdit;
+ QHBoxLayout *hbox = new QHBoxLayout;
+
+ hbox->addWidget(lineEdit);
+ setLayout(hbox);
+ }
+
+ protected:
+ void keyReleaseEvent(QKeyEvent *e) override
+ {
+ releasedKey = e->key();
+ }
+ } dialog;
+
+ dialog.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&dialog));
+
+ QTest::keyPress(dialog.lineEdit, Qt::Key_A);
+ QTest::keyRelease(dialog.lineEdit, Qt::Key_A);
+
+ QCOMPARE(dialog.releasedKey, Qt::Key_A);
+
+ QTest::keyPress(dialog.lineEdit, Qt::Key_Alt);
+ QTest::keyRelease(dialog.lineEdit, Qt::Key_Alt);
+
+ QCOMPARE(dialog.releasedKey, Qt::Key_Alt);
+}
+
+#if QT_CONFIG(shortcut)
+
+void tst_QLineEdit::deleteWordByKeySequence_data()
+{
+ QTest::addColumn<QString>("startText");
+ QTest::addColumn<int>("selectionStart");
+ QTest::addColumn<int>("selectionEnd");
+ QTest::addColumn<int>("cursorPosition");
+ QTest::addColumn<QKeySequence::StandardKey>("key");
+ QTest::addColumn<QString>("expectedText");
+ QTest::addColumn<int>("expectedCursorPosition");
+
+ QTest::newRow("Delete start, no selection")
+ << QStringLiteral("Some Text") << 0 << 0 << 9 << QKeySequence::DeleteStartOfWord
+ << QStringLiteral("Some ") << 5;
+ QTest::newRow("Delete end, no selection")
+ << QStringLiteral("Some Text") << 0 << 0 << 5 << QKeySequence::DeleteEndOfWord
+ << QStringLiteral("Some ") << 5;
+ QTest::newRow("Delete start from middle, no selection")
+ << QStringLiteral("Some Text") << 0 << 0 << 7 << QKeySequence::DeleteStartOfWord
+ << QStringLiteral("Some xt") << 5;
+ QTest::newRow("Delete end from middle, no selection")
+ << QStringLiteral("Some Text") << 0 << 0 << 7 << QKeySequence::DeleteEndOfWord
+ << QStringLiteral("Some Te") << 7;
+ QTest::newRow("Delete end from first, no selection")
+ << QStringLiteral("Some Text") << 0 << 0 << 0 << QKeySequence::DeleteEndOfWord
+ << QStringLiteral("Text") << 0;
+
+ QTest::newRow("Delete start, full selection")
+ << QStringLiteral("Some Text") << 0 << 9 << 0 << QKeySequence::DeleteStartOfWord
+ << QStringLiteral("") << 0;
+ QTest::newRow("Delete end, full selection")
+ << QStringLiteral("Some Text") << 0 << 9 << 0 << QKeySequence::DeleteEndOfWord
+ << QStringLiteral("") << 0;
+ QTest::newRow("Delete start, full selection, single word")
+ << QStringLiteral("Some") << 0 << 4 << 0 << QKeySequence::DeleteStartOfWord
+ << QStringLiteral("") << 0;
+ QTest::newRow("Delete end, full selection, single word")
+ << QStringLiteral("Some") << 0 << 4 << 0 << QKeySequence::DeleteEndOfWord
+ << QStringLiteral("") << 0;
+
+ QTest::newRow("Delete start, word selection")
+ << QStringLiteral("Some Text") << 5 << 9 << 0 << QKeySequence::DeleteStartOfWord
+ << QStringLiteral("Some ") << 5;
+ QTest::newRow("Delete end, word selection")
+ << QStringLiteral("Some Text") << 5 << 9 << 0 << QKeySequence::DeleteEndOfWord
+ << QStringLiteral("Some ") << 5;
+ QTest::newRow("Delete start, partial word selection")
+ << QStringLiteral("Some Text") << 5 << 7 << 0 << QKeySequence::DeleteStartOfWord
+ << QStringLiteral("Some xt") << 5;
+ QTest::newRow("Delete end, partial word selection")
+ << QStringLiteral("Some Text") << 5 << 7 << 0 << QKeySequence::DeleteEndOfWord
+ << QStringLiteral("Some xt") << 5;
+ QTest::newRow("Delete start, partial inner word selection")
+ << QStringLiteral("Some Text") << 6 << 8 << 0 << QKeySequence::DeleteStartOfWord
+ << QStringLiteral("Some Tt") << 6;
+ QTest::newRow("Delete end, partial inner word selection")
+ << QStringLiteral("Some Text") << 6 << 8 << 0 << QKeySequence::DeleteEndOfWord
+ << QStringLiteral("Some Tt") << 6;
+ QTest::newRow("Delete start, selection with space")
+ << QStringLiteral("Some Text") << 3 << 9 << 0 << QKeySequence::DeleteStartOfWord
+ << QStringLiteral("Som") << 3;
+ QTest::newRow("Delete end, selection with space")
+ << QStringLiteral("Some Text") << 3 << 9 << 0 << QKeySequence::DeleteEndOfWord
+ << QStringLiteral("Som") << 3;
+ QTest::newRow("Delete start, partial word selection with space")
+ << QStringLiteral("Some Text") << 3 << 7 << 0 << QKeySequence::DeleteStartOfWord
+ << QStringLiteral("Somxt") << 3;
+ QTest::newRow("Delete end, partial selection with space")
+ << QStringLiteral("Some Text") << 3 << 7 << 0 << QKeySequence::DeleteEndOfWord
+ << QStringLiteral("Somxt") << 3;
+}
+
+void tst_QLineEdit::deleteWordByKeySequence()
+{
+ QFETCH(QString, startText);
+ QFETCH(int, selectionStart);
+ QFETCH(int, selectionEnd);
+ QFETCH(int, cursorPosition);
+ QFETCH(QKeySequence::StandardKey, key);
+ QFETCH(QString, expectedText);
+ QFETCH(int, expectedCursorPosition);
+
+ QWidget widget;
+
+ QLineEdit *lineEdit = new QLineEdit(startText, &widget);
+ lineEdit->setFocus();
+ lineEdit->setCursorPosition(cursorPosition);
+ if (selectionStart != selectionEnd)
+ lineEdit->setSelection(selectionStart, selectionEnd - selectionStart);
+
+ widget.show();
+
+ QVERIFY(QTest::qWaitForWindowActive(&widget));
+
+ QTestEventList keys;
+ addKeySequenceStandardKey(keys, key);
+ keys.simulate(lineEdit);
+
+ QCOMPARE(lineEdit->text(), expectedText);
+ QCOMPARE(lineEdit->selectionStart(), -1);
+ QCOMPARE(lineEdit->selectionEnd(), -1);
+ QCOMPARE(lineEdit->cursorPosition(), expectedCursorPosition);
+}
+
+#endif // QT_CONFIG(shortcut)
+
QTEST_MAIN(tst_QLineEdit)
#include "tst_qlineedit.moc"
diff --git a/tests/auto/widgets/widgets/qmainwindow/BLACKLIST b/tests/auto/widgets/widgets/qmainwindow/BLACKLIST
new file mode 100644
index 0000000000..28b08026d8
--- /dev/null
+++ b/tests/auto/widgets/widgets/qmainwindow/BLACKLIST
@@ -0,0 +1,2 @@
+[QTBUG52175_tabifiedDockWidgetActivated]
+macos arm ci
diff --git a/tests/auto/widgets/widgets/qmainwindow/CMakeLists.txt b/tests/auto/widgets/widgets/qmainwindow/CMakeLists.txt
index 85ce87f764..93f94f78c7 100644
--- a/tests/auto/widgets/widgets/qmainwindow/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qmainwindow/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qmainwindow.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qmainwindow Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmainwindow LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qmainwindow
SOURCES
tst_qmainwindow.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
Qt::WidgetsPrivate
diff --git a/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp b/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp
index e30df32d5d..093af90d1c 100644
--- a/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp
+++ b/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.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>
@@ -68,13 +43,13 @@ public:
}
void timerEvent(QTimerEvent*) override
{
- QCoreApplication::postEvent(m_tb, new QMouseEvent(QEvent::MouseButtonPress, QPoint(6, 7), Qt::LeftButton, {}, {}));
- QCoreApplication::postEvent(m_tb, new QMouseEvent(QEvent::MouseMove, QPoint(7, 8), Qt::LeftButton, Qt::LeftButton, {}));
- QCoreApplication::postEvent(m_tb, new QMouseEvent(QEvent::MouseMove, QPoint(27, 23), Qt::LeftButton, Qt::LeftButton, {}));
- QCoreApplication::postEvent(m_tb, new QMouseEvent(QEvent::MouseMove, QPoint(30, 27), Qt::LeftButton, Qt::LeftButton, {}));
- QCoreApplication::postEvent(m_tb, new QMouseEvent(QEvent::MouseMove, QPoint(162, 109), Qt::LeftButton, Qt::LeftButton, {}));
- QCoreApplication::postEvent(m_tb, new QMouseEvent(QEvent::MouseMove, QPoint(10, 4), Qt::LeftButton, Qt::LeftButton, {}));
- QCoreApplication::postEvent(m_tb, new QMouseEvent(QEvent::MouseButtonRelease, QPoint(9, 4), Qt::LeftButton, {}, {}));
+ QCoreApplication::postEvent(m_tb, new QMouseEvent(QEvent::MouseButtonPress, QPoint(6, 7), m_tb->mapToGlobal(QPoint(6, 7)), Qt::LeftButton, {}, {}));
+ QCoreApplication::postEvent(m_tb, new QMouseEvent(QEvent::MouseMove, QPoint(7, 8), m_tb->mapToGlobal(QPoint(7, 8)), Qt::LeftButton, Qt::LeftButton, {}));
+ QCoreApplication::postEvent(m_tb, new QMouseEvent(QEvent::MouseMove, QPoint(27, 23), m_tb->mapToGlobal(QPoint(27, 23)), Qt::LeftButton, Qt::LeftButton, {}));
+ QCoreApplication::postEvent(m_tb, new QMouseEvent(QEvent::MouseMove, QPoint(30, 27), m_tb->mapToGlobal(QPoint(30, 27)), Qt::LeftButton, Qt::LeftButton, {}));
+ QCoreApplication::postEvent(m_tb, new QMouseEvent(QEvent::MouseMove, QPoint(162, 109), m_tb->mapToGlobal(QPoint(162, 109)), Qt::LeftButton, Qt::LeftButton, {}));
+ QCoreApplication::postEvent(m_tb, new QMouseEvent(QEvent::MouseMove, QPoint(10, 4), m_tb->mapToGlobal(QPoint(10, 4)), Qt::LeftButton, Qt::LeftButton, {}));
+ QCoreApplication::postEvent(m_tb, new QMouseEvent(QEvent::MouseButtonRelease, QPoint(9, 4), m_tb->mapToGlobal(QPoint(6, 7)), Qt::LeftButton, {}, {}));
}
};
@@ -92,8 +67,8 @@ public:
void timerEvent(QTimerEvent*) override
{
- QCoreApplication::postEvent(m_w, new QMouseEvent(QEvent::MouseButtonPress, QPoint(230, 370), Qt::LeftButton, {}, {}));
- QCoreApplication::postEvent(m_w, new QMouseEvent(QEvent::MouseButtonRelease, QPoint(230, 370), Qt::LeftButton, {}, {}));
+ QCoreApplication::postEvent(m_w, new QMouseEvent(QEvent::MouseButtonPress, QPoint(230, 370), m_w->mapToGlobal(QPoint(230, 370)), Qt::LeftButton, {}, {}));
+ QCoreApplication::postEvent(m_w, new QMouseEvent(QEvent::MouseButtonRelease, QPoint(230, 370), m_w->mapToGlobal(QPoint(230, 370)), Qt::LeftButton, {}, {}));
}
};
@@ -111,6 +86,7 @@ private slots:
void iconSize();
void toolButtonStyle();
void menuBar();
+ void customMenuBar();
void centralWidget();
void takeCentralWidget();
void corner();
@@ -128,6 +104,7 @@ private slots:
void restoreStateFromPreviousVersion();
void restoreStateSizeChanged_data();
void restoreStateSizeChanged();
+ void restoreAndModify();
void createPopupMenu();
void hideBeforeLayout();
#ifdef QT_BUILD_INTERNAL
@@ -674,6 +651,18 @@ void tst_QMainWindow::menuBar()
}
}
+// QTBUG-98247
+void tst_QMainWindow::customMenuBar()
+{
+ QMainWindow w;
+ std::unique_ptr<QWidget> menuWidget(new QWidget);
+ w.setMenuWidget(menuWidget.get());
+ QVERIFY(menuWidget->parentWidget());
+ QVERIFY(w.menuBar()); // implicitly calls setMenuBar
+ QVERIFY(!menuWidget->parentWidget());
+ menuWidget.reset();
+}
+
#ifdef QT_BUILD_INTERNAL
void tst_QMainWindow::statusBar()
{
@@ -1352,25 +1341,31 @@ void tst_QMainWindow::restoreState()
dw.setObjectName(QLatin1String("dock"));
mw.addDockWidget(Qt::LeftDockWidgetArea, &dw);
+ QWidgetPrivate *tbp = QWidgetPrivate::get(&tb);
+ QVERIFY(tbp->widgetItem);
+
QByteArray state;
state = mw.saveState();
QVERIFY(mw.restoreState(state));
+ QVERIFY(tbp->widgetItem);
state = mw.saveState(1);
QVERIFY(!mw.restoreState(state));
QVERIFY(mw.restoreState(state, 1));
+ QVERIFY(tbp->widgetItem);
}
//tests the restoration of the previous versions of window settings
void tst_QMainWindow::restoreStateFromPreviousVersion()
{
- QList<QByteArray> restoreData;
- restoreData << QByteArray((char*)restoreData41, sizeof(restoreData41))
- << QByteArray((char*)restoreData42, sizeof(restoreData42))
- << QByteArray((char*)restoreData43, sizeof(restoreData43));
+ const QByteArray restoreData[] = {
+ QByteArray((char*)restoreData41, sizeof(restoreData41)),
+ QByteArray((char*)restoreData42, sizeof(restoreData42)),
+ QByteArray((char*)restoreData43, sizeof(restoreData43)),
+ };
- foreach(QByteArray ba, restoreData) {
+ for (const QByteArray &ba : restoreData) {
QMainWindow win;
win.setCentralWidget(new QTextEdit);
@@ -1443,6 +1438,8 @@ void tst_QMainWindow::restoreStateSizeChanged()
auto mainWindow = QScopedPointer<QMainWindow>(createMainWindow());
mainWindow->restoreGeometry(geometryData);
+ QElapsedTimer timer;
+ timer.start();
mainWindow->restoreState(stateData);
mainWindow->setWindowState(showState);
mainWindow->show();
@@ -1451,8 +1448,97 @@ void tst_QMainWindow::restoreStateSizeChanged()
QDockWidget *dockWidget = mainWindow->findChild<QDockWidget*>("Dock Widget");
QVERIFY(dockWidget);
QCOMPARE(mainWindow->normalGeometry().size(), normalGeometry.size());
- if (sameSize)
- QTRY_COMPARE(dockWidget->width(), dockWidgetWidth);
+ if (sameSize) {
+ // The implementation discards the restored state 150ms after a resize
+ // event. If it takes too long to get here, then the test cannot pass anymore
+ // and we want to XFAIL rather then skip it with some information that might
+ // help us adjust the timeout in QMainWindowLayout.
+ bool expectFail = false;
+ const auto waitForLastResize = [&]() -> bool {
+ if (dockWidget->width() == dockWidgetWidth)
+ return true;
+ if (timer.elapsed() > 150) {
+ QMainWindowLayout *l = mainWindow->findChild<QMainWindowLayout *>();
+ Q_ASSERT(l);
+ if (!l->restoredState) {
+ qWarning("Restored state discarded after %lld", timer.elapsed());
+ expectFail = true;
+ return true;
+ }
+ }
+ return false;
+ };
+ QTRY_VERIFY_WITH_TIMEOUT(waitForLastResize(), 500);
+ if (expectFail) {
+ QEXPECT_FAIL("fullscreen", "Restored state probably discarded too early", Continue);
+ QEXPECT_FAIL("maximized->fullscreen", "Restored state probably discarded too early", Continue);
+ }
+ QCOMPARE(dockWidget->width(), dockWidgetWidth);
+ }
+}
+
+/*!
+ If a main window's state is restored but also modified, then we
+ might have to forget the restored state to avoid dangling pointers.
+ See comment in QMainWindowLayout::applyRestoredState() and QTBUG-120025.
+*/
+void tst_QMainWindow::restoreAndModify()
+{
+ class MainWindow : public QMainWindow
+ {
+ public:
+ MainWindow()
+ {
+ setCentralWidget(new QTextEdit);
+
+ customers = new QDockWidget(tr("Customers"), this);
+ customers->setObjectName("Customers");
+ customers->setAllowedAreas(Qt::LeftDockWidgetArea |
+ Qt::RightDockWidgetArea);
+ customers->setWidget(new QTextEdit);
+ addDockWidget(Qt::RightDockWidgetArea, customers);
+
+ paragraphs = new QDockWidget(tr("Paragraphs"), this);
+ paragraphs->setObjectName("Paragraphs");
+ paragraphs->setWidget(new QTextEdit);
+ addDockWidget(Qt::RightDockWidgetArea, paragraphs);
+ }
+
+ void restore()
+ {
+ if (!savedGeometry.isEmpty())
+ restoreGeometry(savedGeometry);
+ setWindowState(Qt::WindowMaximized);
+ if (!savedState.isEmpty())
+ restoreState(savedState);
+
+ tabifyDockWidget(customers, paragraphs);
+ }
+ protected:
+ void closeEvent(QCloseEvent *event) override
+ {
+ savedGeometry = saveGeometry();
+ savedState = saveState();
+
+ return QMainWindow::closeEvent(event);
+ }
+ private:
+ QByteArray savedGeometry;
+ QByteArray savedState;
+
+ QDockWidget *customers;
+ QDockWidget *paragraphs;
+
+ } mainWindow;
+
+ mainWindow.restore();
+ mainWindow.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&mainWindow));
+ mainWindow.close();
+
+ mainWindow.restore();
+ mainWindow.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&mainWindow));
}
void tst_QMainWindow::createPopupMenu()
@@ -1651,25 +1737,25 @@ void MoveSeparator::apply(QMainWindow *mw) const
QMap<QString, QRect> dockWidgetGeometries(QMainWindow *mw)
{
QMap<QString, QRect> result;
- QList<QDockWidget*> dockWidgets = mw->findChildren<QDockWidget*>();
- foreach (QDockWidget *dw, dockWidgets)
+ const QList<QDockWidget*> dockWidgets = mw->findChildren<QDockWidget*>();
+ for (QDockWidget *dw : dockWidgets)
result.insert(dw->objectName(), dw->geometry());
return result;
}
#define COMPARE_DOCK_WIDGET_GEOS(_oldGeos, _newGeos) \
{ \
- QMap<QString, QRect> __oldGeos = _oldGeos; \
- QMap<QString, QRect> __newGeos = _newGeos; \
- QCOMPARE(__newGeos.keys(), __oldGeos.keys()); \
- QStringList __keys = __newGeos.keys(); \
- foreach (const QString &key, __keys) { \
- QRect __r1 = __oldGeos[key]; \
- QRect __r2 = __newGeos[key]; \
- if (__r1 != __r2) \
- qWarning() << key << __r1 << __r2; \
+ QMap<QString, QRect> _v_oldGeos = _oldGeos; \
+ QMap<QString, QRect> _v_newGeos = _newGeos; \
+ QCOMPARE(_v_newGeos.keys(), _v_oldGeos.keys()); \
+ const QStringList _v_keys = _v_newGeos.keys(); \
+ for (const QString &key : _v_keys) { \
+ QRect _v_r1 = _v_oldGeos[key]; \
+ QRect _v_r2 = _v_newGeos[key]; \
+ if (_v_r1 != _v_r2) \
+ qWarning() << key << _v_r1 << _v_r2; \
} \
- QCOMPARE(__newGeos, __oldGeos); \
+ QCOMPARE(_v_newGeos, _v_oldGeos); \
}
#ifdef QT_BUILD_INTERNAL
@@ -1715,8 +1801,8 @@ void tst_QMainWindow::saveRestore_data()
#ifdef QT_BUILD_INTERNAL
void tst_QMainWindow::saveRestore()
{
- QFETCH(AddList, addList);
- QFETCH(MoveList, moveList);
+ QFETCH(const AddList, addList);
+ QFETCH(const MoveList, moveList);
QByteArray stateData;
QMap<QString, QRect> dockWidgetGeos;
@@ -1728,12 +1814,12 @@ void tst_QMainWindow::saveRestore()
QTextEdit centralWidget("The rain in Spain falls mainly on the plains");
mainWindow.setCentralWidget(&centralWidget);
- foreach (const AddDockWidget &adw, addList)
+ for (const AddDockWidget &adw : addList)
adw.apply(&mainWindow);
mainWindow.show();
- foreach (const MoveSeparator &ms, moveList)
+ for (const MoveSeparator &ms : moveList)
ms.apply(&mainWindow);
dockWidgetGeos = dockWidgetGeometries(&mainWindow);
@@ -1751,7 +1837,7 @@ void tst_QMainWindow::saveRestore()
QTextEdit centralWidget("The rain in Spain falls mainly on the plains");
mainWindow.setCentralWidget(&centralWidget);
- foreach (const AddDockWidget &adw, addList)
+ for (const AddDockWidget &adw : addList)
adw.apply(&mainWindow);
mainWindow.show();
@@ -1768,7 +1854,7 @@ void tst_QMainWindow::saveRestore()
QTextEdit centralWidget("The rain in Spain falls mainly on the plains");
mainWindow.setCentralWidget(&centralWidget);
- foreach (const AddDockWidget &adw, addList)
+ for (const AddDockWidget &adw : addList)
adw.apply(&mainWindow);
mainWindow.resize(size);
mainWindow.restoreState(stateData);
@@ -1819,11 +1905,11 @@ void tst_QMainWindow::setCursor()
QVERIFY(QTest::qWaitForWindowActive(&mw));
QCOMPARE(cur.shape(), mw.cursor().shape());
- QHoverEvent enterE(QEvent::HoverEnter, QPoint(10,10), QPoint());
+ QHoverEvent enterE(QEvent::HoverEnter, QPoint(10,10), QPoint(), QPoint());
mw.event(&enterE);
QCOMPARE(cur.shape(), mw.cursor().shape());
- QHoverEvent leaveE(QEvent::HoverLeave, QPoint(), QPoint());
+ QHoverEvent leaveE(QEvent::HoverLeave, QPoint(), QPoint(), QPoint());
mw.event(&leaveE);
QCOMPARE(cur.shape(), mw.cursor().shape());
}
@@ -1844,7 +1930,7 @@ void tst_QMainWindow::addToolbarAfterShow()
void tst_QMainWindow::centralWidgetSize()
{
if (qGuiApp->styleHints()->showIsFullScreen())
- QSKIP("The platform is auto maximizing, so the test makes no sense");;
+ QSKIP("The platform is auto maximizing, so the test makes no sense");
QMainWindow mainWindow;
mainWindow.menuBar()->addMenu("menu");
@@ -2076,10 +2162,11 @@ void tst_QMainWindow::resizeDocks()
mw.setDockNestingEnabled(true);
mw.resize(1800, 600);
- foreach (const AddDockWidget &i, addList)
+ for (const AddDockWidget &i : std::as_const(addList))
i.apply(&mw);
- foreach (QDockWidget *dw, mw.findChildren<QDockWidget *>())
+ const auto dockWidgets = mw.findChildren<QDockWidget *>();
+ for (QDockWidget *dw : dockWidgets)
dw->setStyleSheet( "* { background-color: " + dw->objectName() +" }");
mw.setCentralWidget(new QTextEdit);
@@ -2088,11 +2175,11 @@ void tst_QMainWindow::resizeDocks()
QVERIFY(QTest::qWaitForWindowExposed(&mw));
QFETCH(Qt::Orientation, orientation);
- QFETCH(QStringList, docks);
+ QFETCH(const QStringList, docks);
QFETCH(QList<int>, sizes);
QList<QDockWidget *> list;
- foreach (const QString &name, docks) {
+ for (const QString &name : docks) {
QDockWidget *d = mw.findChild<QDockWidget *>(name);
QVERIFY(d);
list << d;
@@ -2104,14 +2191,14 @@ void tst_QMainWindow::resizeDocks()
int totalFromList = 0;
int actualTotal = 0;
- for (int i = 0; i < docks.count(); ++i) {
+ for (int i = 0; i < docks.size(); ++i) {
totalFromList += sizes[i];
QSize s = list[i]->size();
actualTotal += (orientation == Qt::Horizontal) ? s.width() : s.height();
// qDebug() << list[i] << list[i]->size() << sizes[i];
}
- for (int i = 0; i < docks.count(); ++i) {
+ for (int i = 0; i < docks.size(); ++i) {
QSize s = list[i]->size();
int value = (orientation == Qt::Horizontal) ? s.width() : s.height();
QCOMPARE(value, qRound(sizes[i]*actualTotal/double(totalFromList)));
diff --git a/tests/auto/widgets/widgets/qmdiarea/BLACKLIST b/tests/auto/widgets/widgets/qmdiarea/BLACKLIST
index 3091b73269..c3234bf56c 100644
--- a/tests/auto/widgets/widgets/qmdiarea/BLACKLIST
+++ b/tests/auto/widgets/widgets/qmdiarea/BLACKLIST
@@ -1,15 +1,7 @@
[tileSubWindows]
-ubuntu-16.04
-rhel-7.6
centos
opensuse-leap
macos
-ubuntu-18.04
-ubuntu-20.04
-macos
-rhel-7.4
-macos
-opensuse-42.3
[resizeTimer]
macos
diff --git a/tests/auto/widgets/widgets/qmdiarea/CMakeLists.txt b/tests/auto/widgets/widgets/qmdiarea/CMakeLists.txt
index 9586d69352..5f61dc8664 100644
--- a/tests/auto/widgets/widgets/qmdiarea/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qmdiarea/CMakeLists.txt
@@ -1,32 +1,38 @@
-# Generated from qmdiarea.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qmdiarea Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmdiarea LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qmdiarea
SOURCES
tst_qmdiarea.cpp
DEFINES
QT_NO_CAST_FROM_ASCII
QT_NO_CAST_TO_ASCII
- INCLUDE_DIRECTORIES
- .
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::GuiPrivate
Qt::Widgets
+ Qt::WidgetsPrivate
)
## Scopes:
#####################################################################
qt_internal_extend_target(tst_qmdiarea CONDITION TARGET Qt::OpenGL
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::OpenGL
)
qt_internal_extend_target(tst_qmdiarea CONDITION APPLE
- PUBLIC_LIBRARIES
+ LIBRARIES
${FWSecurity}
)
diff --git a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp
index 225b349f08..0f652f2900 100644
--- a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp
+++ b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.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>
@@ -49,6 +24,8 @@
#endif
#include <QStyleHints>
+#include <QtWidgets/private/qapplication_p.h>
+
static const Qt::WindowFlags DefaultWindowFlags
= Qt::SubWindow | Qt::WindowSystemMenuHint
| Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint;
@@ -163,7 +140,7 @@ static bool verifyArrangement(QMdiArea *mdiArea, Arrangement arrangement, const
case Tiled:
{
// Calculate the number of rows and columns.
- const int n = subWindows.count();
+ const int n = subWindows.size();
const int numColumns = qMax(qCeil(qSqrt(qreal(n))), 1);
const int numRows = qMax((n % numColumns) ? (n / numColumns + 1) : (n / numColumns), 1);
@@ -199,7 +176,7 @@ static bool verifyArrangement(QMdiArea *mdiArea, Arrangement arrangement, const
// QWidget::childAt with the position of the first one and subsequently adding
// dx and dy.
QPoint subWindowPos(20, 5);
- foreach (int expectedIndex, expectedIndices) {
+ for (int expectedIndex : expectedIndices) {
QMdiSubWindow *expected = subWindows.at(expectedIndex);
expected->raise();
if (mdiArea->viewport()->childAt(subWindowPos) != expected)
@@ -210,7 +187,7 @@ static bool verifyArrangement(QMdiArea *mdiArea, Arrangement arrangement, const
}
// Restore stacking order.
- foreach (QMdiSubWindow *subWindow, activationOrderList) {
+ for (QMdiSubWindow *subWindow : activationOrderList) {
mdiArea->setActiveSubWindow(subWindow);
qApp->processEvents();
}
@@ -283,6 +260,10 @@ private slots:
void task_236750();
void qtbug92240_title_data();
void qtbug92240_title();
+ void tabbedview_singleSubWindow();
+ void tabbedview_activefirst();
+ void tabbedview_activesecond();
+ void tabbedview_activethird();
private:
QMdiSubWindow *activeWindow;
@@ -326,7 +307,7 @@ void tst_QMdiArea::subWindowActivated()
QSignalSpy spy(workspace, SIGNAL(subWindowActivated(QMdiSubWindow*)));
connect( workspace, SIGNAL(subWindowActivated(QMdiSubWindow*)), this, SLOT(activeChanged(QMdiSubWindow*)));
mw.show();
- qApp->setActiveWindow(&mw);
+ QApplicationPrivate::setActiveWindow(&mw);
QFETCH( int, count );
int i;
@@ -339,12 +320,12 @@ void tst_QMdiArea::subWindowActivated()
widget->show();
qApp->processEvents();
QVERIFY( activeWindow == workspace->activeSubWindow() );
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
}
QList<QMdiSubWindow *> windows = workspace->subWindowList();
- QCOMPARE( (int)windows.count(), count );
+ QCOMPARE( (int)windows.size(), count );
for ( i = 0; i < count; ++i ) {
QMdiSubWindow *window = windows.at(i);
@@ -368,13 +349,13 @@ void tst_QMdiArea::subWindowActivated()
workspace->activeSubWindow()->close();
qApp->processEvents();
QCOMPARE(activeWindow, workspace->activeSubWindow());
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
}
QVERIFY(!activeWindow);
QVERIFY(!workspace->activeSubWindow());
- QCOMPARE(workspace->subWindowList().count(), 0);
+ QCOMPARE(workspace->subWindowList().size(), 0);
{
workspace->hide();
@@ -382,14 +363,14 @@ void tst_QMdiArea::subWindowActivated()
widget->setAttribute(Qt::WA_DeleteOnClose);
QMdiSubWindow *window = workspace->addSubWindow(widget);
widget->show();
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
workspace->show();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
QVERIFY( activeWindow == window );
window->close();
qApp->processEvents();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
QVERIFY( activeWindow == 0 );
}
@@ -401,15 +382,15 @@ void tst_QMdiArea::subWindowActivated()
QMdiSubWindow *window = workspace->addSubWindow(widget);
widget->showMaximized();
qApp->sendPostedEvents();
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
spy.clear();
workspace->show();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
QVERIFY( activeWindow == window );
window->close();
qApp->processEvents();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
QVERIFY( activeWindow == 0 );
}
@@ -419,13 +400,13 @@ void tst_QMdiArea::subWindowActivated()
widget->setAttribute(Qt::WA_DeleteOnClose);
QMdiSubWindow *window = workspace->addSubWindow(widget);
widget->showMinimized();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
QVERIFY( activeWindow == window );
QCOMPARE(workspace->activeSubWindow(), window);
window->close();
qApp->processEvents();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
QVERIFY(!workspace->activeSubWindow());
QVERIFY(!activeWindow);
@@ -453,12 +434,12 @@ void tst_QMdiArea::subWindowActivated2()
QSignalSpy spy(&mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)));
for (int i = 0; i < 5; ++i)
mdiArea.addSubWindow(new QWidget);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
mdiArea.show();
mdiArea.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&mdiArea));
- QTRY_COMPARE(spy.count(), 5);
+ QTRY_COMPARE(spy.size(), 5);
QCOMPARE(mdiArea.activeSubWindow(), mdiArea.subWindowList().back());
spy.clear();
@@ -467,13 +448,13 @@ void tst_QMdiArea::subWindowActivated2()
QMdiSubWindow *staysOnTopWindow = mdiArea.subWindowList().at(3);
staysOnTopWindow->setWindowFlags(Qt::WindowStaysOnTopHint);
mdiArea.setActiveSubWindow(staysOnTopWindow);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(mdiArea.activeSubWindow(), staysOnTopWindow);
spy.clear();
QMdiSubWindow *activeSubWindow = mdiArea.subWindowList().at(2);
mdiArea.setActiveSubWindow(activeSubWindow);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(mdiArea.activeSubWindow(), activeSubWindow);
spy.clear();
@@ -481,7 +462,7 @@ void tst_QMdiArea::subWindowActivated2()
// is unchanged after hide/show.
mdiArea.hide();
QTest::qWait(100);
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QVERIFY(!mdiArea.activeSubWindow());
QCOMPARE(mdiArea.currentSubWindow(), activeSubWindow);
spy.clear();
@@ -509,7 +490,7 @@ void tst_QMdiArea::subWindowActivated2()
#endif
if (!QGuiApplication::platformName().compare(QLatin1String("xcb"), Qt::CaseInsensitive))
QSKIP("QTBUG-25298: Unstable on some X11 window managers");
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QVERIFY(!mdiArea.activeSubWindow());
QCOMPARE(mdiArea.currentSubWindow(), activeSubWindow);
spy.clear();
@@ -519,7 +500,7 @@ void tst_QMdiArea::subWindowActivated2()
mdiArea.showNormal();
mdiArea.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&mdiArea));
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QCOMPARE(mdiArea.activeSubWindow(), activeSubWindow);
spy.clear();
}
@@ -534,7 +515,7 @@ void tst_QMdiArea::subWindowActivatedWithMinimize()
QSignalSpy spy(workspace, SIGNAL(subWindowActivated(QMdiSubWindow*)));
connect( workspace, SIGNAL(subWindowActivated(QMdiSubWindow*)), this, SLOT(activeChanged(QMdiSubWindow*)) );
mw.show();
- qApp->setActiveWindow(&mw);
+ QApplicationPrivate::setActiveWindow(&mw);
QWidget *widget = new QWidget(workspace);
widget->setAttribute(Qt::WA_DeleteOnClose);
QMdiSubWindow *window1 = workspace->addSubWindow(widget);
@@ -556,7 +537,7 @@ void tst_QMdiArea::subWindowActivatedWithMinimize()
QVERIFY(!workspace->activeSubWindow());
QVERIFY(!activeWindow);
- QVERIFY( workspace->subWindowList().count() == 0 );
+ QVERIFY( workspace->subWindowList().size() == 0 );
}
void tst_QMdiArea::showWindows()
@@ -679,7 +660,7 @@ void tst_QMdiArea::changeWindowTitle()
#endif
mw->show();
- qApp->setActiveWindow(mw);
+ QApplicationPrivate::setActiveWindow(mw);
#ifdef USE_SHOW
mw->showFullScreen();
@@ -835,14 +816,14 @@ void tst_QMdiArea::fixedSize()
}
QList<QMdiSubWindow *> windows = ws->subWindowList();
- for (i = 0; i < (int)windows.count(); ++i) {
+ for (i = 0; i < (int)windows.size(); ++i) {
QMdiSubWindow *child = windows.at(i);
QCOMPARE(child->size(), fixed);
}
ws->cascadeSubWindows();
ws->resize(800, 800);
- for (i = 0; i < (int)windows.count(); ++i) {
+ for (i = 0; i < (int)windows.size(); ++i) {
QMdiSubWindow *child = windows.at(i);
QCOMPARE(child->size(), fixed);
}
@@ -850,13 +831,13 @@ void tst_QMdiArea::fixedSize()
ws->tileSubWindows();
ws->resize(800, 800);
- for (i = 0; i < (int)windows.count(); ++i) {
+ for (i = 0; i < (int)windows.size(); ++i) {
QMdiSubWindow *child = windows.at(i);
QCOMPARE(child->size(), fixed);
}
ws->resize(500, 500);
- for (i = 0; i < (int)windows.count(); ++i) {
+ for (i = 0; i < (int)windows.size(); ++i) {
QMdiSubWindow *child = windows.at(i);
delete child;
}
@@ -924,7 +905,7 @@ void tst_QMdiArea::setActiveSubWindow()
QSignalSpy spy(&workspace, SIGNAL(subWindowActivated(QMdiSubWindow*)));
connect(&workspace, SIGNAL(subWindowActivated(QMdiSubWindow*)), this, SLOT(activeChanged(QMdiSubWindow*)));
- qApp->setActiveWindow(&workspace);
+ QApplicationPrivate::setActiveWindow(&workspace);
// Activate hidden windows
const int windowCount = 10;
@@ -935,7 +916,7 @@ void tst_QMdiArea::setActiveSubWindow()
QVERIFY(windows[i]->isHidden());
workspace.setActiveSubWindow(windows[i]);
}
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
QVERIFY(!activeWindow);
spy.clear();
@@ -945,7 +926,7 @@ void tst_QMdiArea::setActiveSubWindow()
QVERIFY(!windows[i]->isHidden());
workspace.setActiveSubWindow(windows[i]);
qApp->processEvents();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(activeWindow, windows[i]);
spy.clear();
}
@@ -953,7 +934,7 @@ void tst_QMdiArea::setActiveSubWindow()
// Deactivate active window
QCOMPARE(workspace.activeSubWindow(), windows[windowCount - 1]);
workspace.setActiveSubWindow(0);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QVERIFY(!activeWindow);
QVERIFY(!workspace.activeSubWindow());
@@ -983,7 +964,7 @@ void tst_QMdiArea::activeSubWindow()
mainWindow.addDockWidget(Qt::LeftDockWidgetArea, dockWidget);
mainWindow.show();
- qApp->setActiveWindow(&mainWindow);
+ QApplicationPrivate::setActiveWindow(&mainWindow);
QVERIFY(QTest::qWaitForWindowActive(&mainWindow));
QCOMPARE(mdiArea->activeSubWindow(), subWindow);
QCOMPARE(qApp->focusWidget(), (QWidget *)subWindowLineEdit);
@@ -1006,15 +987,15 @@ void tst_QMdiArea::activeSubWindow()
dummyTopLevel.show();
QVERIFY(QTest::qWaitForWindowExposed(&dummyTopLevel));
- qApp->setActiveWindow(&dummyTopLevel);
+ QApplicationPrivate::setActiveWindow(&dummyTopLevel);
QCOMPARE(mdiArea->activeSubWindow(), subWindow);
- qApp->setActiveWindow(&mainWindow);
+ QApplicationPrivate::setActiveWindow(&mainWindow);
QCOMPARE(mdiArea->activeSubWindow(), subWindow);
//task 202657
dockWidgetLineEdit->setFocus();
- qApp->setActiveWindow(&mainWindow);
+ QApplicationPrivate::setActiveWindow(&mainWindow);
QVERIFY(dockWidgetLineEdit->hasFocus());
}
@@ -1027,7 +1008,7 @@ void tst_QMdiArea::currentSubWindow()
for (int i = 0; i < 5; ++i)
mdiArea.addSubWindow(new QLineEdit)->show();
- qApp->setActiveWindow(&mdiArea);
+ QApplicationPrivate::setActiveWindow(&mdiArea);
QCOMPARE(qApp->activeWindow(), (QWidget *)&mdiArea);
// Check that the last added window is the active and the current.
@@ -1042,7 +1023,7 @@ void tst_QMdiArea::currentSubWindow()
// Move focus to another top-level and check that we still
// have an active window.
- qApp->setActiveWindow(&dummyTopLevel);
+ QApplicationPrivate::setActiveWindow(&dummyTopLevel);
QCOMPARE(qApp->activeWindow(), (QWidget *)&dummyTopLevel);
QVERIFY(mdiArea.activeSubWindow());
@@ -1055,7 +1036,7 @@ void tst_QMdiArea::currentSubWindow()
QCOMPARE(mdiArea.currentSubWindow(), mdiArea.subWindowList().front());
// Activate mdi area and check that active == current.
- qApp->setActiveWindow(&mdiArea);
+ QApplicationPrivate::setActiveWindow(&mdiArea);
active = mdiArea.activeSubWindow();
QVERIFY(active);
QCOMPARE(mdiArea.activeSubWindow(), mdiArea.subWindowList().front());
@@ -1064,11 +1045,11 @@ void tst_QMdiArea::currentSubWindow()
QCOMPARE(mdiArea.activeSubWindow(), active);
QCOMPARE(mdiArea.currentSubWindow(), active);
- qApp->setActiveWindow(&dummyTopLevel);
+ QApplicationPrivate::setActiveWindow(&dummyTopLevel);
QVERIFY(mdiArea.activeSubWindow());
QCOMPARE(mdiArea.currentSubWindow(), active);
- qApp->setActiveWindow(&mdiArea);
+ QApplicationPrivate::setActiveWindow(&mdiArea);
active->show();
QCOMPARE(mdiArea.activeSubWindow(), active);
@@ -1098,11 +1079,11 @@ void tst_QMdiArea::addAndRemoveWindows()
QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
{ // addSubWindow with large widget
- QCOMPARE(workspace.subWindowList().count(), 0);
+ QCOMPARE(workspace.subWindowList().size(), 0);
QWidget *window = workspace.addSubWindow(new LargeWidget);
QVERIFY(window);
qApp->processEvents();
- QCOMPARE(workspace.subWindowList().count(), 1);
+ QCOMPARE(workspace.subWindowList().size(), 1);
QCOMPARE(window->windowFlags(), DefaultWindowFlags);
QCOMPARE(window->size(), workspace.viewport()->size());
}
@@ -1113,7 +1094,7 @@ void tst_QMdiArea::addAndRemoveWindows()
workspace.addSubWindow(window);
QVERIFY(window);
qApp->processEvents();
- QCOMPARE(workspace.subWindowList().count(), 2);
+ QCOMPARE(workspace.subWindowList().size(), 2);
QCOMPARE(window->windowFlags(), DefaultWindowFlags);
QCOMPARE(window->size(), window->minimumSize());
}
@@ -1125,7 +1106,7 @@ void tst_QMdiArea::addAndRemoveWindows()
workspace.addSubWindow(window);
QVERIFY(window);
qApp->processEvents();
- QCOMPARE(workspace.subWindowList().count(), 3);
+ QCOMPARE(workspace.subWindowList().size(), 3);
QCOMPARE(window->windowFlags(), DefaultWindowFlags);
QCOMPARE(window->size(), QSize(1500, 1500));
}
@@ -1134,7 +1115,7 @@ void tst_QMdiArea::addAndRemoveWindows()
QTest::ignoreMessage(QtWarningMsg, "QMdiArea::addSubWindow: null pointer to widget");
QWidget *window = workspace.addSubWindow(0);
QVERIFY(!window);
- QCOMPARE(workspace.subWindowList().count(), 3);
+ QCOMPARE(workspace.subWindowList().size(), 3);
}
{ // addChildWindow
@@ -1143,7 +1124,7 @@ void tst_QMdiArea::addAndRemoveWindows()
qApp->processEvents();
QCOMPARE(window->windowFlags(), DefaultWindowFlags);
window->setWidget(new QWidget);
- QCOMPARE(workspace.subWindowList().count(), 4);
+ QCOMPARE(workspace.subWindowList().size(), 4);
QTest::ignoreMessage(QtWarningMsg, "QMdiArea::addSubWindow: window is already added");
workspace.addSubWindow(window);
}
@@ -1151,15 +1132,16 @@ void tst_QMdiArea::addAndRemoveWindows()
{ // addChildWindow with 0 pointer
QTest::ignoreMessage(QtWarningMsg, "QMdiArea::addSubWindow: null pointer to widget");
workspace.addSubWindow(0);
- QCOMPARE(workspace.subWindowList().count(), 4);
+ QCOMPARE(workspace.subWindowList().size(), 4);
}
// removeSubWindow
- foreach (QWidget *window, workspace.subWindowList()) {
+ const auto subWindows = workspace.subWindowList();
+ for (QWidget *window : subWindows) {
workspace.removeSubWindow(window);
delete window;
}
- QCOMPARE(workspace.subWindowList().count(), 0);
+ QCOMPARE(workspace.subWindowList().size(), 0);
// removeSubWindow with 0 pointer
QTest::ignoreMessage(QtWarningMsg, "QMdiArea::removeSubWindow: null pointer to widget");
@@ -1167,7 +1149,7 @@ void tst_QMdiArea::addAndRemoveWindows()
workspace.addSubWindow(new QPushButton(QLatin1String("Dummy to make workspace non-empty")));
qApp->processEvents();
- QCOMPARE(workspace.subWindowList().count(), 1);
+ QCOMPARE(workspace.subWindowList().size(), 1);
// removeSubWindow with window not inside workspace
QTest::ignoreMessage(QtWarningMsg,"QMdiArea::removeSubWindow: window is not inside workspace");
@@ -1209,20 +1191,20 @@ void tst_QMdiArea::addAndRemoveWindowsWithReparenting()
// 0 because the window list contains widgets and not actual
// windows. Silly, but that's the behavior.
- QCOMPARE(workspace.subWindowList().count(), 0);
+ QCOMPARE(workspace.subWindowList().size(), 0);
window.setWidget(new QWidget);
qApp->processEvents();
- QCOMPARE(workspace.subWindowList().count(), 1);
+ QCOMPARE(workspace.subWindowList().size(), 1);
window.setParent(0); // Will also reset window flags
- QCOMPARE(workspace.subWindowList().count(), 0);
+ QCOMPARE(workspace.subWindowList().size(), 0);
window.setParent(&workspace);
- QCOMPARE(workspace.subWindowList().count(), 1);
+ QCOMPARE(workspace.subWindowList().size(), 1);
QCOMPARE(window.windowFlags(), DefaultWindowFlags);
QTest::ignoreMessage(QtWarningMsg, "QMdiArea::addSubWindow: window is already added");
workspace.addSubWindow(&window);
- QCOMPARE(workspace.subWindowList().count(), 1);
+ QCOMPARE(workspace.subWindowList().size(), 1);
}
class MySubWindow : public QMdiSubWindow
@@ -1273,23 +1255,23 @@ void tst_QMdiArea::closeWindows()
{
QMdiArea workspace;
workspace.show();
- qApp->setActiveWindow(&workspace);
+ QApplicationPrivate::setActiveWindow(&workspace);
// Close widget
QWidget *widget = new QWidget;
QMdiSubWindow *subWindow = workspace.addSubWindow(widget);
qApp->processEvents();
- QCOMPARE(workspace.subWindowList().count(), 1);
+ QCOMPARE(workspace.subWindowList().size(), 1);
subWindow->close();
- QCOMPARE(workspace.subWindowList().count(), 0);
+ QCOMPARE(workspace.subWindowList().size(), 0);
// Close window
QWidget *window = workspace.addSubWindow(new QWidget);
qApp->processEvents();
- QCOMPARE(workspace.subWindowList().count(), 1);
+ QCOMPARE(workspace.subWindowList().size(), 1);
window->close();
qApp->processEvents();
- QCOMPARE(workspace.subWindowList().count(), 0);
+ QCOMPARE(workspace.subWindowList().size(), 0);
const int windowCount = 10;
@@ -1297,7 +1279,7 @@ void tst_QMdiArea::closeWindows()
for (int i = 0; i < windowCount; ++i)
workspace.addSubWindow(new QWidget)->show();
qApp->processEvents();
- QCOMPARE(workspace.subWindowList().count(), windowCount);
+ QCOMPARE(workspace.subWindowList().size(), windowCount);
int activeSubWindowCount = 0;
while (workspace.activeSubWindow()) {
workspace.activeSubWindow()->close();
@@ -1305,19 +1287,19 @@ void tst_QMdiArea::closeWindows()
++activeSubWindowCount;
}
QCOMPARE(activeSubWindowCount, windowCount);
- QCOMPARE(workspace.subWindowList().count(), 0);
+ QCOMPARE(workspace.subWindowList().size(), 0);
// Close all windows
for (int i = 0; i < windowCount; ++i)
workspace.addSubWindow(new QWidget)->show();
qApp->processEvents();
- QCOMPARE(workspace.subWindowList().count(), windowCount);
+ QCOMPARE(workspace.subWindowList().size(), windowCount);
QSignalSpy spy(&workspace, SIGNAL(subWindowActivated(QMdiSubWindow*)));
connect(&workspace, SIGNAL(subWindowActivated(QMdiSubWindow*)), this, SLOT(activeChanged(QMdiSubWindow*)));
workspace.closeAllSubWindows();
qApp->processEvents();
- QCOMPARE(workspace.subWindowList().count(), 0);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(workspace.subWindowList().size(), 0);
+ QCOMPARE(spy.size(), 1);
QVERIFY(!activeWindow);
}
@@ -1325,7 +1307,7 @@ void tst_QMdiArea::activateNextAndPreviousWindow()
{
QMdiArea workspace;
workspace.show();
- qApp->setActiveWindow(&workspace);
+ QApplicationPrivate::setActiveWindow(&workspace);
const int windowCount = 10;
QMdiSubWindow *windows[windowCount];
@@ -1343,7 +1325,7 @@ void tst_QMdiArea::activateNextAndPreviousWindow()
workspace.activateNextSubWindow();
qApp->processEvents();
QCOMPARE(workspace.activeSubWindow(), windows[i]);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
}
QVERIFY(activeWindow);
@@ -1355,7 +1337,7 @@ void tst_QMdiArea::activateNextAndPreviousWindow()
workspace.activatePreviousSubWindow();
qApp->processEvents();
QCOMPARE(workspace.activeSubWindow(), windows[i]);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
if (i % 2 == 0)
windows[i]->hide(); // 10, 8, 6, 4, 2, 0
@@ -1367,7 +1349,7 @@ void tst_QMdiArea::activateNextAndPreviousWindow()
// activateNextSubWindow with every 2nd window hidden
for (int i = 0; i < windowCount / 2; ++i) {
workspace.activateNextSubWindow(); // 1, 3, 5, 7, 9
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
}
QCOMPARE(workspace.activeSubWindow(), windows[windowCount - 1]);
@@ -1375,7 +1357,7 @@ void tst_QMdiArea::activateNextAndPreviousWindow()
// activatePreviousSubWindow with every 2nd window hidden
for (int i = 0; i < windowCount / 2; ++i) {
workspace.activatePreviousSubWindow(); // 7, 5, 3, 1, 9
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
}
QCOMPARE(workspace.activeSubWindow(), windows[windowCount - 1]);
@@ -1409,7 +1391,7 @@ void tst_QMdiArea::subWindowList()
QMdiArea workspace;
workspace.show();
- qApp->setActiveWindow(&workspace);
+ QApplicationPrivate::setActiveWindow(&workspace);
QVERIFY(QTest::qWaitForWindowActive(&workspace));
QList<QMdiSubWindow *> activationOrder;
@@ -1422,8 +1404,8 @@ void tst_QMdiArea::subWindowList()
{
QList<QMdiSubWindow *> widgets = workspace.subWindowList(windowOrder);
- QCOMPARE(widgets.count(), windowCount);
- for (int i = 0; i < widgets.count(); ++i)
+ QCOMPARE(widgets.size(), windowCount);
+ for (int i = 0; i < widgets.size(); ++i)
QCOMPARE(widgets.at(i), windows[i]);
}
@@ -1442,9 +1424,9 @@ void tst_QMdiArea::subWindowList()
}
if (windowOrder == QMdiArea::StackingOrder) {
- QCOMPARE(subWindows.at(subWindows.count() - 1), windows[staysOnTop1]);
- QCOMPARE(subWindows.at(subWindows.count() - 2), windows[activeSubWindow]);
- QCOMPARE(subWindows.count(), windowCount);
+ QCOMPARE(subWindows.at(subWindows.size() - 1), windows[staysOnTop1]);
+ QCOMPARE(subWindows.at(subWindows.size() - 2), windows[activeSubWindow]);
+ QCOMPARE(subWindows.size(), windowCount);
} else { // ActivationHistoryOrder
QCOMPARE(subWindows, activationOrder);
}
@@ -1459,11 +1441,11 @@ void tst_QMdiArea::subWindowList()
activationOrder.move(activationOrder.indexOf(windows[activeSubWindow]), windowCount - 1);
QList<QMdiSubWindow *> widgets = workspace.subWindowList(windowOrder);
- QCOMPARE(widgets.count(), windowCount);
+ QCOMPARE(widgets.size(), windowCount);
if (windowOrder == QMdiArea::StackingOrder) {
- QCOMPARE(widgets.at(widgets.count() - 1), windows[staysOnTop2]);
- QCOMPARE(widgets.at(widgets.count() - 2), windows[staysOnTop1]);
- QCOMPARE(widgets.at(widgets.count() - 3), windows[activeSubWindow]);
+ QCOMPARE(widgets.at(widgets.size() - 1), windows[staysOnTop2]);
+ QCOMPARE(widgets.at(widgets.size() - 2), windows[staysOnTop1]);
+ QCOMPARE(widgets.at(widgets.size() - 3), windows[activeSubWindow]);
} else { // ActivationHistory
QCOMPARE(widgets, activationOrder);
}
@@ -1473,8 +1455,8 @@ void tst_QMdiArea::subWindowList()
widgets = workspace.subWindowList(windowOrder);
if (windowOrder == QMdiArea::StackingOrder) {
- QCOMPARE(widgets.at(widgets.count() - 1), windows[activeSubWindow]);
- QCOMPARE(widgets.at(widgets.count() - 2), windows[staysOnTop1]);
+ QCOMPARE(widgets.at(widgets.size() - 1), windows[activeSubWindow]);
+ QCOMPARE(widgets.at(widgets.size() - 2), windows[staysOnTop1]);
QCOMPARE(widgets.at(0), windows[staysOnTop2]);
} else { // ActivationHistoryOrder
QCOMPARE(widgets, activationOrder);
@@ -1485,9 +1467,9 @@ void tst_QMdiArea::subWindowList()
widgets = workspace.subWindowList(windowOrder);
if (windowOrder == QMdiArea::StackingOrder) {
- QCOMPARE(widgets.at(widgets.count() - 1), windows[staysOnTop2]);
- QCOMPARE(widgets.at(widgets.count() - 2), windows[staysOnTop1]);
- QCOMPARE(widgets.at(widgets.count() - 3), windows[activeSubWindow]);
+ QCOMPARE(widgets.at(widgets.size() - 1), windows[staysOnTop2]);
+ QCOMPARE(widgets.at(widgets.size() - 2), windows[staysOnTop1]);
+ QCOMPARE(widgets.at(widgets.size() - 3), windows[activeSubWindow]);
} else { // ActivationHistoryOrder
QCOMPARE(widgets, activationOrder);
}
@@ -1497,9 +1479,9 @@ void tst_QMdiArea::subWindowList()
widgets = workspace.subWindowList(windowOrder);
if (windowOrder == QMdiArea::StackingOrder) {
- QCOMPARE(widgets.at(widgets.count() - 1), windows[staysOnTop1]);
- QCOMPARE(widgets.at(widgets.count() - 2), windows[staysOnTop2]);
- QCOMPARE(widgets.at(widgets.count() - 3), windows[activeSubWindow]);
+ QCOMPARE(widgets.at(widgets.size() - 1), windows[staysOnTop1]);
+ QCOMPARE(widgets.at(widgets.size() - 2), windows[staysOnTop2]);
+ QCOMPARE(widgets.at(widgets.size() - 3), windows[activeSubWindow]);
} else { // ActivationHistoryOrder
QCOMPARE(widgets, activationOrder);
}
@@ -1540,14 +1522,14 @@ void tst_QMdiArea::setViewport()
qApp->processEvents();
QList<QMdiSubWindow *> windowsBeforeViewportChange = workspace.subWindowList();
- QCOMPARE(windowsBeforeViewportChange.count(), windowCount);
+ QCOMPARE(windowsBeforeViewportChange.size(), windowCount);
workspace.setViewport(new QWidget);
qApp->processEvents();
QVERIFY(workspace.viewport() != firstViewport);
QList<QMdiSubWindow *> windowsAfterViewportChange = workspace.subWindowList();
- QCOMPARE(windowsAfterViewportChange.count(), windowCount);
+ QCOMPARE(windowsAfterViewportChange.size(), windowCount);
QCOMPARE(windowsAfterViewportChange, windowsBeforeViewportChange);
// for (int i = 0; i < windowCount; ++i) {
@@ -1563,7 +1545,7 @@ void tst_QMdiArea::setViewport()
delete workspace.viewport();
qApp->processEvents();
- QCOMPARE(workspace.subWindowList().count(), 0);
+ QCOMPARE(workspace.subWindowList().size(), 0);
QVERIFY(!workspace.activeSubWindow());
}
@@ -1705,7 +1687,8 @@ void tst_QMdiArea::tileSubWindows()
QTRY_COMPARE(workspace.size(), QSize(350, 150));
const QSize minSize(600, 130);
- foreach (QMdiSubWindow *subWindow, workspace.subWindowList())
+ const auto subWindows = workspace.subWindowList();
+ for (QMdiSubWindow *subWindow : subWindows)
subWindow->setMinimumSize(minSize);
QCOMPARE(workspace.size(), QSize(350, 150));
@@ -1803,7 +1786,7 @@ void tst_QMdiArea::cascadeAndTileSubWindows()
#endif
QCOMPARE(windows.at(2)->geometry().top() - windows.at(1)->geometry().top(), dy);
- for (int i = 0; i < windows.count(); ++i) {
+ for (int i = 0; i < windows.size(); ++i) {
QMdiSubWindow *window = windows.at(i);
if (i % 3 == 0) {
QVERIFY(window->isMinimized());
@@ -1863,7 +1846,7 @@ void tst_QMdiArea::resizeMaximizedChildWindows()
int newSize = startSize + increment * windowCount;
QCOMPARE(workspaceSize, QSize(newSize, newSize));
- foreach (QWidget *window, windows)
+ for (QWidget *window : std::as_const(windows))
QCOMPARE(window->rect(), workspace.contentsRect());
}
@@ -1888,7 +1871,7 @@ void tst_QMdiArea::focusWidgetAfterAddSubWindow()
mdiArea.show();
view->show();
- qApp->setActiveWindow(&mdiArea);
+ QApplicationPrivate::setActiveWindow(&mdiArea);
QCOMPARE(qApp->focusWidget(), static_cast<QWidget *>(lineEdit2));
}
@@ -1897,7 +1880,7 @@ void tst_QMdiArea::dontMaximizeSubWindowOnActivation()
QMdiArea mdiArea;
mdiArea.show();
QVERIFY(QTest::qWaitForWindowExposed(&mdiArea));
- qApp->setActiveWindow(&mdiArea);
+ QApplicationPrivate::setActiveWindow(&mdiArea);
// Add one maximized window.
mdiArea.addSubWindow(new QWidget)->showMaximized();
@@ -1908,16 +1891,13 @@ void tst_QMdiArea::dontMaximizeSubWindowOnActivation()
for (int i = 0; i < 5; ++i) {
QMdiSubWindow *window = mdiArea.addSubWindow(new QWidget);
window->show();
-#if defined Q_OS_QNX
- QEXPECT_FAIL("", "QTBUG-38231", Abort);
-#endif
QVERIFY(window->isMaximized());
qApp->processEvents();
}
// Verify that activated windows still are maximized on activation.
- QList<QMdiSubWindow *> subWindows = mdiArea.subWindowList();
- for (int i = 0; i < subWindows.count(); ++i) {
+ const QList<QMdiSubWindow *> subWindows = mdiArea.subWindowList();
+ for (int i = 0; i < subWindows.size(); ++i) {
mdiArea.activateNextSubWindow();
QMdiSubWindow *window = subWindows.at(i);
QCOMPARE(mdiArea.activeSubWindow(), window);
@@ -1928,7 +1908,7 @@ void tst_QMdiArea::dontMaximizeSubWindowOnActivation()
// Restore active window and verify that other windows aren't
// maximized on activation.
mdiArea.activeSubWindow()->showNormal();
- for (int i = 0; i < subWindows.count(); ++i) {
+ for (int i = 0; i < subWindows.size(); ++i) {
mdiArea.activateNextSubWindow();
QMdiSubWindow *window = subWindows.at(i);
QCOMPARE(mdiArea.activeSubWindow(), window);
@@ -1942,7 +1922,7 @@ void tst_QMdiArea::dontMaximizeSubWindowOnActivation()
int indexOfMaximized = subWindows.indexOf(mdiArea.activeSubWindow());
// Verify that windows are not maximized on activation.
- for (int i = 0; i < subWindows.count(); ++i) {
+ for (int i = 0; i < subWindows.size(); ++i) {
mdiArea.activateNextSubWindow();
QMdiSubWindow *window = subWindows.at(i);
QCOMPARE(mdiArea.activeSubWindow(), window);
@@ -1953,7 +1933,7 @@ void tst_QMdiArea::dontMaximizeSubWindowOnActivation()
QVERIFY(mdiArea.activeSubWindow()->isMaximized());
// Minimize all windows.
- foreach (QMdiSubWindow *window, subWindows) {
+ for (QMdiSubWindow *window : subWindows) {
window->showMinimized();
QVERIFY(window->isMinimized());
qApp->processEvents();
@@ -1964,7 +1944,7 @@ void tst_QMdiArea::dontMaximizeSubWindowOnActivation()
mdiArea.activeSubWindow()->showMaximized();
// Verify that minimized windows are maximized on activation.
- for (int i = 0; i < subWindows.count(); ++i) {
+ for (int i = 0; i < subWindows.size(); ++i) {
mdiArea.activateNextSubWindow();
QMdiSubWindow *window = subWindows.at(i);
QCOMPARE(mdiArea.activeSubWindow(), window);
@@ -1974,7 +1954,7 @@ void tst_QMdiArea::dontMaximizeSubWindowOnActivation()
// Verify that activated windows are maximized after closing
// the active window
- for (int i = 0; i < subWindows.count(); ++i) {
+ for (int i = 0; i < subWindows.size(); ++i) {
QVERIFY(mdiArea.activeSubWindow());
QVERIFY(mdiArea.activeSubWindow()->isMaximized());
mdiArea.activeSubWindow()->close();
@@ -2226,7 +2206,7 @@ void tst_QMdiArea::setActivationOrder()
mdiArea.show();
QVERIFY(QTest::qWaitForWindowExposed(&mdiArea));
- for (int i = 0; i < subWindows.count(); ++i) {
+ for (int i = 0; i < subWindows.size(); ++i) {
mdiArea.activateNextSubWindow();
QCOMPARE(mdiArea.activeSubWindow(), subWindows.at(i));
qApp->processEvents();
@@ -2285,12 +2265,12 @@ void tst_QMdiArea::tabBetweenSubWindows()
mdiArea.show();
QVERIFY(QTest::qWaitForWindowExposed(&mdiArea));
- qApp->setActiveWindow(&mdiArea);
+ QApplicationPrivate::setActiveWindow(&mdiArea);
QWidget *focusWidget = subWindows.back()->widget();
QCOMPARE(qApp->focusWidget(), focusWidget);
QSignalSpy spy(&mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)));
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
// Walk through the entire list of sub windows.
#ifdef Q_OS_MAC
@@ -2298,7 +2278,7 @@ void tst_QMdiArea::tabBetweenSubWindows()
#endif
QVERIFY(tabBetweenSubWindowsIn(&mdiArea));
QCOMPARE(mdiArea.activeSubWindow(), subWindows.back());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
mdiArea.setActiveSubWindow(subWindows.front());
QCOMPARE(mdiArea.activeSubWindow(), subWindows.front());
@@ -2307,12 +2287,12 @@ void tst_QMdiArea::tabBetweenSubWindows()
// Walk through the entire list of sub windows in the opposite direction (Ctrl-Shift-Tab).
QVERIFY(tabBetweenSubWindowsIn(&mdiArea, -1, true));
QCOMPARE(mdiArea.activeSubWindow(), subWindows.front());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
// Ctrl-Tab-Tab-Tab
QVERIFY(tabBetweenSubWindowsIn(&mdiArea, 3));
QCOMPARE(mdiArea.activeSubWindow(), subWindows.at(3));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
mdiArea.setActiveSubWindow(subWindows.at(1));
QCOMPARE(mdiArea.activeSubWindow(), subWindows.at(1));
@@ -2321,7 +2301,7 @@ void tst_QMdiArea::tabBetweenSubWindows()
// Quick switch (Ctrl-Tab once) -> switch back to the previously active sub-window.
QVERIFY(tabBetweenSubWindowsIn(&mdiArea, 1));
QCOMPARE(mdiArea.activeSubWindow(), subWindows.at(3));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
}
void tst_QMdiArea::setViewMode()
@@ -2340,7 +2320,7 @@ void tst_QMdiArea::setViewMode()
QVERIFY(QTest::qWaitForWindowExposed(&mdiArea));
QMdiSubWindow *activeSubWindow = mdiArea.activeSubWindow();
- QList<QMdiSubWindow *> subWindows = mdiArea.subWindowList();
+ const QList<QMdiSubWindow *> subWindows = mdiArea.subWindowList();
// Default.
QVERIFY(!activeSubWindow->isMaximized());
@@ -2355,7 +2335,7 @@ void tst_QMdiArea::setViewMode()
QVERIFY(tabBar);
QVERIFY(tabBar->isVisible());
- QCOMPARE(tabBar->count(), subWindows.count());
+ QCOMPARE(tabBar->count(), subWindows.size());
QVERIFY(activeSubWindow->isMaximized());
QCOMPARE(tabBar->currentIndex(), subWindows.indexOf(activeSubWindow));
@@ -2409,13 +2389,12 @@ void tst_QMdiArea::setViewMode()
QVERIFY(tabBar->isTabEnabled(tabIndex));
// Remove sub-windows and make sure the tab is removed.
- foreach (QMdiSubWindow *subWindow, subWindows) {
+ for (QMdiSubWindow *subWindow : subWindows) {
if (subWindow != activeSubWindow) {
mdiArea.removeSubWindow(subWindow);
delete subWindow;
}
}
- subWindows.clear();
QCOMPARE(tabBar->count(), 1);
// Go back to default (QMdiArea::SubWindowView).
@@ -2616,8 +2595,11 @@ void tst_QMdiArea::nativeSubWindows()
// No native widgets.
QVERIFY(!mdiArea.viewport()->internalWinId());
- foreach (QMdiSubWindow *subWindow, mdiArea.subWindowList())
- QVERIFY(!subWindow->internalWinId());
+ {
+ const auto subWindows = mdiArea.subWindowList();
+ for (QMdiSubWindow *subWindow : subWindows)
+ QVERIFY(!subWindow->internalWinId());
+ }
QWidget *nativeWidget = new QWidget;
QVERIFY(nativeWidget->winId()); // enforce native window.
@@ -2626,8 +2608,11 @@ void tst_QMdiArea::nativeSubWindows()
// The viewport and all the sub-windows must be native.
QVERIFY(mdiArea.viewport()->internalWinId());
- foreach (QMdiSubWindow *subWindow, mdiArea.subWindowList())
- QVERIFY(subWindow->internalWinId());
+ {
+ const auto subWindows = mdiArea.subWindowList();
+ for (QMdiSubWindow *subWindow : subWindows)
+ QVERIFY(subWindow->internalWinId());
+ }
// Add a non-native widget. This should become native.
QMdiSubWindow *subWindow = new QMdiSubWindow;
@@ -2648,8 +2633,11 @@ void tst_QMdiArea::nativeSubWindows()
// The viewport and all the sub-windows must be native.
QVERIFY(mdiArea.viewport()->internalWinId());
- foreach (QMdiSubWindow *subWindow, mdiArea.subWindowList())
- QVERIFY(subWindow->internalWinId());
+ {
+ const auto subWindows = mdiArea.subWindowList();
+ for (QMdiSubWindow *subWindow : subWindows)
+ QVERIFY(subWindow->internalWinId());
+ }
}
{ // Make a sub-window native *after* it's added to the area.
@@ -2665,9 +2653,12 @@ void tst_QMdiArea::nativeSubWindows()
// All the sub-windows should be native at this point
QVERIFY(mdiArea.viewport()->internalWinId());
- foreach (QMdiSubWindow *subWindow, mdiArea.subWindowList())
+ {
+ const auto subWindows = mdiArea.subWindowList();
+ for (QMdiSubWindow *subWindow : subWindows)
QVERIFY(subWindow->internalWinId());
}
+ }
}
void tst_QMdiArea::task_209615()
@@ -2738,6 +2729,75 @@ void tst_QMdiArea::qtbug92240_title()
QTRY_COMPARE(w.windowTitle(), QLatin1String("QTBUG-92240 - [2]"));
}
+void tst_QMdiArea::tabbedview_singleSubWindow()
+{
+ // With only one sub-window, setViewMode() before addSubWindow(); and addSubWindow()
+ // before show(), ensure the sub-window is properly activated.
+ QMdiArea mdiArea;
+ mdiArea.setViewMode(QMdiArea::TabbedView);
+ auto *w = new QWidget(&mdiArea);
+ mdiArea.addSubWindow(w);
+ mdiArea.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&mdiArea));
+ auto *sub = mdiArea.subWindowList().at(0);
+ QCOMPARE(mdiArea.activeSubWindow(), sub);
+ QVERIFY(sub->isMaximized());
+}
+
+static void setupMdiAreaWithTabbedView(QMdiArea &mdiArea)
+{
+ mdiArea.setViewMode(QMdiArea::TabbedView);
+
+ auto *mdiWin1 = new QWidget(&mdiArea);
+ mdiWin1->setWindowTitle(QLatin1String("Sub1"));
+ mdiArea.addSubWindow(mdiWin1);
+
+ auto *mdiWin2 = new QWidget(&mdiArea);
+ mdiWin2->setWindowTitle(QLatin1String("Sub2"));
+ mdiArea.addSubWindow(mdiWin2);
+
+ auto *mdiWin3 = new QWidget(&mdiArea);
+ mdiWin3->setWindowTitle(QLatin1String("Sub3"));
+ mdiArea.addSubWindow(mdiWin3);
+}
+
+void tst_QMdiArea::tabbedview_activefirst()
+{
+ QMdiArea mdiArea;
+ setupMdiAreaWithTabbedView(mdiArea);
+
+ auto sub0 = mdiArea.subWindowList().at(0);
+ mdiArea.setActiveSubWindow(sub0);
+ mdiArea.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&mdiArea));
+ QCOMPARE(mdiArea.activeSubWindow(), sub0);
+}
+
+void tst_QMdiArea::tabbedview_activesecond()
+{
+ QMdiArea mdiArea;
+ setupMdiAreaWithTabbedView(mdiArea);
+
+ auto sub1 = mdiArea.subWindowList().at(1);
+ mdiArea.setActiveSubWindow(sub1);
+ mdiArea.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&mdiArea));
+ QCOMPARE(mdiArea.activeSubWindow(), sub1);
+}
+
+void tst_QMdiArea::tabbedview_activethird()
+{
+ QMdiArea mdiArea;
+ setupMdiAreaWithTabbedView(mdiArea);
+
+ auto sub2 = mdiArea.subWindowList().at(2);
+ mdiArea.setActiveSubWindow(sub2);
+ mdiArea.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&mdiArea));
+ QCOMPARE(mdiArea.activeSubWindow(), sub2);
+}
+
+
QTEST_MAIN(tst_QMdiArea)
#include "tst_qmdiarea.moc"
diff --git a/tests/auto/widgets/widgets/qmdisubwindow/CMakeLists.txt b/tests/auto/widgets/widgets/qmdisubwindow/CMakeLists.txt
index 2c72f7d4e1..45b7b74ac4 100644
--- a/tests/auto/widgets/widgets/qmdisubwindow/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qmdisubwindow/CMakeLists.txt
@@ -1,18 +1,23 @@
-# Generated from qmdisubwindow.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qmdisubwindow Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmdisubwindow LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qmdisubwindow
SOURCES
tst_qmdisubwindow.cpp
DEFINES
QT_NO_CAST_FROM_ASCII
QT_NO_CAST_TO_ASCII
- INCLUDE_DIRECTORIES
- .
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
Qt::WidgetsPrivate
diff --git a/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp b/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp
index a4283de59e..38808d1702 100644
--- a/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp
+++ b/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 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) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "qmdisubwindow.h"
#include "private/qmdisubwindow_p.h"
@@ -45,10 +20,13 @@
#include <QStyleOptionTitleBar>
#include <QPushButton>
#include <QScreen>
+#include <QScrollBar>
#include <QSizeGrip>
#include <QSignalSpy>
#include <QList>
+#include <QtWidgets/private/qapplication_p.h>
+
QT_BEGIN_NAMESPACE
extern bool qt_tab_all_widgets();
QT_END_NAMESPACE
@@ -221,6 +199,7 @@ private slots:
void styleChange();
void testFullScreenState();
void testRemoveBaseWidget();
+ void testRespectMinimumSize();
};
void tst_QMdiSubWindow::initTestCase()
@@ -405,7 +384,7 @@ void tst_QMdiSubWindow::mainWindowSupport()
mainWindow.setCentralWidget(workspace);
mainWindow.show();
mainWindow.menuBar()->setVisible(true);
- QApplication::setActiveWindow(&mainWindow);
+ QApplicationPrivate::setActiveWindow(&mainWindow);
bool nativeMenuBar = mainWindow.menuBar()->isNativeMenuBar();
// QMainWindow's window title is empty, so on a platform which does NOT have a native menubar,
@@ -494,7 +473,7 @@ void tst_QMdiSubWindow::mainWindowSupport()
workspace->activateNextSubWindow();
QCoreApplication::processEvents();
- for (QMdiSubWindow *window : qAsConst(windows)) {
+ for (QMdiSubWindow *window : std::as_const(windows)) {
QCOMPARE(workspace->activeSubWindow(), window);
QVERIFY(window->isMaximized());
QVERIFY(window->maximizedButtonsWidget());
@@ -531,7 +510,7 @@ void tst_QMdiSubWindow::emittingOfSignals()
workspace.setWindowTitle(QLatin1String(QTest::currentTestFunction()));
workspace.show();
QCoreApplication::processEvents();
- QApplication::setActiveWindow(&workspace);
+ QApplicationPrivate::setActiveWindow(&workspace);
QMdiSubWindow *window = qobject_cast<QMdiSubWindow *>(workspace.addSubWindow(new QWidget));
QCoreApplication::processEvents();
window->show();
@@ -551,9 +530,9 @@ void tst_QMdiSubWindow::emittingOfSignals()
int count = 0;
if (signal == SIGNAL(aboutToActivate())) {
- count += spy.count();
+ count += spy.size();
} else {
- for (int i = 0; i < spy.count(); ++i) {
+ for (int i = 0; i < spy.size(); ++i) {
Qt::WindowStates oldState = qvariant_cast<Qt::WindowStates>(spy.at(i).at(0));
Qt::WindowStates newState = qvariant_cast<Qt::WindowStates>(spy.at(i).at(1));
if (watchedState != Qt::WindowNoState) {
@@ -576,7 +555,7 @@ void tst_QMdiSubWindow::emittingOfSignals()
spy.clear();
triggerSignal(window, &workspace, signal);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
delete window;
window = nullptr;
@@ -975,6 +954,8 @@ void tst_QMdiSubWindow::mouseDoubleClick()
if (!window->style()->styleHint(QStyle::SH_TitleBar_NoBorder, &options, window))
height += window->isMinimized() ? 8 : 4;
QPoint mousePosition(window->width() / 2, height - 1);
+ if (window->style()->inherits("QWindows11Style"))
+ mousePosition = QPoint(8, height - 1);
sendMouseMove(window, mousePosition, Qt::NoButton);
// Without Qt::WindowShadeButtonHint flag set
@@ -1002,8 +983,10 @@ void tst_QMdiSubWindow::mouseDoubleClick()
window->showMinimized();
QVERIFY(window->isMinimized());
+ //Process QEvent::WindowStateChange
+ QCoreApplication::processEvents();
sendMouseDoubleClick(window, mousePosition);
- QVERIFY(!window->isMinimized());
+ QTRY_VERIFY(!window->isMinimized());
QCOMPARE(window->geometry(), originalGeometry);
}
@@ -1053,7 +1036,7 @@ void tst_QMdiSubWindow::setSystemMenu()
subWindow->setSystemMenu(systemMenu);
QCOMPARE(subWindow->systemMenu(), qobject_cast<QMenu *>(systemMenu));
QCOMPARE(subWindow->systemMenu()->parentWidget(), static_cast<QWidget *>(subWindow));
- QCOMPARE(subWindow->systemMenu()->actions().count(), 1);
+ QCOMPARE(subWindow->systemMenu()->actions().size(), 1);
// Show the new system menu
QVERIFY(!QApplication::activePopupWidget());
@@ -1157,7 +1140,7 @@ void tst_QMdiSubWindow::restoreFocus()
topArea.show();
box->show();
- QApplication::setActiveWindow(&topArea);
+ QApplicationPrivate::setActiveWindow(&topArea);
QMdiSubWindow *expectedFocusWindow = nestedWorkspace->subWindowList().last();
QVERIFY(expectedFocusWindow);
QVERIFY(expectedFocusWindow->widget());
@@ -1249,7 +1232,7 @@ void tst_QMdiSubWindow::restoreFocusOverCreation()
subWidget1->m_lineEdit2->setFocus();
subWindow1->show();
mdiArea.show();
- QApplication::setActiveWindow(&mdiArea);
+ QApplicationPrivate::setActiveWindow(&mdiArea);
QVERIFY(QTest::qWaitForWindowActive(&mdiArea));
QCOMPARE(QApplication::focusWidget(), subWidget1->m_lineEdit2);
@@ -1277,9 +1260,9 @@ void tst_QMdiSubWindow::changeFocusWithTab()
mdiArea.setWindowTitle(QLatin1String(QTest::currentTestFunction()));
mdiArea.addSubWindow(widget);
mdiArea.show();
- QCOMPARE(mdiArea.subWindowList().count(), 1);
+ QCOMPARE(mdiArea.subWindowList().size(), 1);
- QApplication::setActiveWindow(&mdiArea);
+ QApplicationPrivate::setActiveWindow(&mdiArea);
QCOMPARE(QApplication::focusWidget(), static_cast<QWidget *>(firstLineEdit));
// Next
@@ -1359,7 +1342,7 @@ void tst_QMdiSubWindow::closeEvent()
QVERIFY(window->close());
QCOMPARE(closeSpy.count(), 3);
- QCOMPARE(mdiArea.subWindowList().count(), 0);
+ QCOMPARE(mdiArea.subWindowList().size(), 0);
}
// There exists more tests in QMdiArea which covers window title support
@@ -1394,7 +1377,7 @@ void tst_QMdiSubWindow::setWindowTitle()
// other widgets which are not real top-level widgets).
QCOMPARE(window->windowTitle(), expectedWindowTitle);
- textEdit->setWindowModified(true);;
+ textEdit->setWindowModified(true);
expectedWindowTitle = QLatin1String("Override child title");
window->setWindowTitle(expectedWindowTitle);
QVERIFY(window->isWindowModified());
@@ -1567,9 +1550,6 @@ void tst_QMdiSubWindow::hideAndShow()
#if !defined (Q_OS_DARWIN)
QVERIFY(menuBar->cornerWidget(Qt::TopRightCorner));
-#if defined Q_OS_QNX
- QEXPECT_FAIL("", "QTBUG-38231", Abort);
-#endif
QVERIFY(subWindow->maximizedButtonsWidget());
QVERIFY(subWindow->maximizedSystemMenuIconWidget());
QCOMPARE(menuBar->cornerWidget(Qt::TopRightCorner), subWindow->maximizedButtonsWidget());
@@ -1800,9 +1780,6 @@ void tst_QMdiSubWindow::replaceMenuBarWhileMaximized()
QCoreApplication::processEvents();
-#if defined Q_OS_QNX
- QEXPECT_FAIL("", "QTBUG-38231", Abort);
-#endif
QVERIFY(subWindow->maximizedButtonsWidget());
QVERIFY(subWindow->maximizedSystemMenuIconWidget());
QCOMPARE(menuBar1->cornerWidget(Qt::TopLeftCorner), subWindow->maximizedSystemMenuIconWidget());
@@ -1894,7 +1871,6 @@ void tst_QMdiSubWindow::closeOnDoubleClick()
void tst_QMdiSubWindow::setFont()
{
- QSKIP("This test function is unstable in CI, please see QTBUG-22544");
QMdiArea mdiArea;
mdiArea.setWindowTitle(QLatin1String(QTest::currentTestFunction()));
QMdiSubWindow *subWindow = mdiArea.addSubWindow(new TestPushButton(QLatin1String("test")));
@@ -1980,7 +1956,7 @@ void tst_QMdiSubWindow::task_182852()
mainWindow.setCentralWidget(workspace);
mainWindow.show();
mainWindow.menuBar()->setVisible(true);
- QApplication::setActiveWindow(&mainWindow);
+ QApplicationPrivate::setActiveWindow(&mainWindow);
if (mainWindow.menuBar()->isNativeMenuBar())
return; // The main window's title is not overwritten if we have a native menubar (macOS, Unity etc.)
@@ -2130,7 +2106,7 @@ void tst_QMdiSubWindow::styleChange()
// subWindowActivated should NOT be activated by a style change,
// even if internally QMdiSubWindow un-minimizes subwindows temporarily.
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
}
void tst_QMdiSubWindow::testFullScreenState()
@@ -2169,6 +2145,36 @@ void tst_QMdiSubWindow::testRemoveBaseWidget()
delete widget1;
}
+void tst_QMdiSubWindow::testRespectMinimumSize() // QTBUG-100494
+{
+ QMdiArea mdiArea;
+ mdiArea.resize(400, 400);
+ mdiArea.setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ mdiArea.setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+
+ auto vlay = new QVBoxLayout;
+ vlay->addWidget(new QPushButton(QLatin1String("btn1-1")));
+ vlay->addSpacerItem(new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding));
+ vlay->addWidget(new QPushButton(QLatin1String("btn1-2")));
+ auto w1 = new QWidget;
+ w1->setLayout(vlay);
+ w1->resize(300, 200);
+ w1->setMinimumSize(200, 150);
+ auto sw = new QMdiSubWindow;
+ sw->setWidget(w1);
+ sw->resize(w1->size());
+ mdiArea.addSubWindow(sw);
+ sw->showMaximized();
+
+ mdiArea.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&mdiArea));
+ QVERIFY(!mdiArea.horizontalScrollBar()->isVisible());
+ QVERIFY(!mdiArea.verticalScrollBar()->isVisible());
+ mdiArea.resize(150, 100);
+ QTRY_VERIFY(mdiArea.horizontalScrollBar()->isVisible());
+ QTRY_VERIFY(mdiArea.verticalScrollBar()->isVisible());
+}
+
QTEST_MAIN(tst_QMdiSubWindow)
#include "tst_qmdisubwindow.moc"
diff --git a/tests/auto/widgets/widgets/qmenu/BLACKLIST b/tests/auto/widgets/widgets/qmenu/BLACKLIST
index 230512769c..88484ddffa 100644
--- a/tests/auto/widgets/widgets/qmenu/BLACKLIST
+++ b/tests/auto/widgets/widgets/qmenu/BLACKLIST
@@ -1,10 +1,6 @@
[task258920_mouseBorder]
macos
-[layoutDirection]
-macos
# Fails when enabling synchronous expose events QTBUG-62092
-[pushButtonPopulateOnAboutToShow]
-macos
[tearOff]
macos
[submenuTearOffDontClose]
@@ -20,6 +16,7 @@ android
android
[pushButtonPopulateOnAboutToShow]
android
+wayland
[QTBUG8122_widgetActionCrashOnClose]
android
[click_while_dismissing_submenu]
@@ -29,3 +26,6 @@ android
[QTBUG_89082_actionTipsHide]
macos ci # Can't move cursor (QTBUG-76312)
windows-10 ci
+# QTBUG-87424
+[transientParent]
+android
diff --git a/tests/auto/widgets/widgets/qmenu/CMakeLists.txt b/tests/auto/widgets/widgets/qmenu/CMakeLists.txt
index 8e596a6b5b..1716ab85da 100644
--- a/tests/auto/widgets/widgets/qmenu/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qmenu/CMakeLists.txt
@@ -1,17 +1,25 @@
-# Generated from qmenu.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qmenu Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmenu LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qmenu
SOURCES
tst_qmenu.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::GuiPrivate
Qt::TestPrivate
Qt::Widgets
+ Qt::WidgetsPrivate
)
## Scopes:
@@ -20,7 +28,7 @@ qt_internal_add_test(tst_qmenu
qt_internal_extend_target(tst_qmenu CONDITION MACOS
SOURCES
tst_qmenu_mac.mm
- PUBLIC_LIBRARIES
+ LIBRARIES
objc
)
diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
index 4b46c05568..5602b8cd3f 100644
--- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
+++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.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>
#include <QtTest/private/qtesthelpers_p.h>
@@ -52,6 +27,9 @@
#include <qpa/qplatformtheme.h>
#include <qpa/qplatformintegration.h>
+#include <QtWidgets/private/qapplication_p.h>
+#include <QtWidgets/private/qmenu_p.h>
+
using namespace QTestPrivate;
Q_DECLARE_METATYPE(Qt::Key);
@@ -118,6 +96,7 @@ private slots:
void QTBUG_89082_actionTipsHide();
void QTBUG8122_widgetActionCrashOnClose();
void widgetActionTriggerClosesMenu();
+ void transientParent();
void QTBUG_10735_crashWithDialog();
#ifdef Q_OS_MAC
@@ -134,6 +113,9 @@ private slots:
void tearOffMenuNotDisplayed();
void QTBUG_61039_menu_shortcuts();
void screenOrientationChangedCloseMenu();
+ void deleteWhenTriggered();
+
+ void nestedTearOffDetached();
protected slots:
void onActivated(QAction*);
@@ -281,11 +263,11 @@ void tst_QMenu::onStatusMessageChanged(const QString &s)
void tst_QMenu::addActionsAndClear()
{
- QCOMPARE(menus[0]->actions().count(), 0);
+ QCOMPARE(menus[0]->actions().size(), 0);
createActions();
- QCOMPARE(menus[0]->actions().count(), 8);
+ QCOMPARE(menus[0]->actions().size(), 8);
menus[0]->clear();
- QCOMPARE(menus[0]->actions().count(), 0);
+ QCOMPARE(menus[0]->actions().size(), 0);
}
static void testFunction0() {}
@@ -505,7 +487,7 @@ void tst_QMenu::focus()
QPushButton button("Push me", &window);
centerOnScreen(&window);
window.show();
- qApp->setActiveWindow(&window);
+ QApplicationPrivate::setActiveWindow(&window);
QVERIFY(button.hasFocus());
QCOMPARE(QApplication::focusWidget(), (QWidget *)&button);
@@ -549,7 +531,7 @@ void tst_QMenu::overrideMenuAction()
m->addAction(aQuit);
w.show();
- QApplication::setActiveWindow(&w);
+ QApplicationPrivate::setActiveWindow(&w);
w.setFocus();
QVERIFY(QTest::qWaitForWindowActive(&w));
QVERIFY(w.hasFocus());
@@ -917,13 +899,20 @@ private:
void tst_QMenu::activeSubMenuPositionExec()
{
-
+#ifdef Q_OS_ANDROID
+ // QTBUG-87424
+ QSKIP("Android: This hangs. Figure out why.");
+#endif
SubMenuPositionExecMenu menu;
menu.exec(QGuiApplication::primaryScreen()->availableGeometry().center());
}
void tst_QMenu::task242454_sizeHint()
{
+#ifdef Q_OS_ANDROID
+ // QTBUG-87424
+ QSKIP("Android: This hangs. Figure out why.");
+#endif
QMenu menu;
QString s = QLatin1String("foo\nfoo\nfoo\nfoo");
menu.addAction(s);
@@ -1052,12 +1041,16 @@ public:
// Mouse move related signals for Windows Mobile unavailable
void tst_QMenu::task258920_mouseBorder()
{
+ const QRect screenGeometry = QGuiApplication::primaryScreen()->availableGeometry();
Menu258920 menu;
+ QCursor::setPos(screenGeometry.topLeft());
+ if (!QTest::qWaitFor([screenGeometry]{ return QCursor::pos() == screenGeometry.topLeft(); }))
+ QSKIP("Can't move cursor out of the way");
// For styles which inherit from QWindowsStyle, styleHint(QStyle::SH_Menu_MouseTracking) is true.
menu.setMouseTracking(true);
QAction *action = menu.addAction("test");
- const QPoint center = QGuiApplication::primaryScreen()->availableGeometry().center();
+ const QPoint center = screenGeometry.center();
menu.popup(center);
QVERIFY(QTest::qWaitForWindowExposed(&menu));
QRect actionRect = menu.actionGeometry(action);
@@ -1153,14 +1146,18 @@ void tst_QMenu::pushButtonPopulateOnAboutToShow()
QSKIP("Your window manager won't allow a window against the bottom of the screen");
}
- QTimer::singleShot(300, buttonMenu, SLOT(hide()));
QTest::mouseClick(&b, Qt::LeftButton, Qt::NoModifier, b.rect().center());
+ QVERIFY(QTest::qWaitForWindowExposed(buttonMenu));
+ QTest::qWait(300);
+ buttonMenu->hide();
QVERIFY2(!buttonMenu->geometry().intersects(b.geometry()), msgGeometryIntersects(buttonMenu->geometry(), b.geometry()));
// note: we're assuming that, if we previously got the desired geometry, we'll get it here too
b.move(10, screen.bottom()-buttonMenu->height()-5);
- QTimer::singleShot(300, buttonMenu, SLOT(hide()));
QTest::mouseClick(&b, Qt::LeftButton, Qt::NoModifier, b.rect().center());
+ QVERIFY(QTest::qWaitForWindowExposed(buttonMenu));
+ QTest::qWait(300);
+ buttonMenu->hide();
QVERIFY2(!buttonMenu->geometry().intersects(b.geometry()), msgGeometryIntersects(buttonMenu->geometry(), b.geometry()));
}
@@ -1275,7 +1272,7 @@ void tst_QMenu::click_while_dismissing_submenu()
//the submenu must have been hidden for the bug to be triggered
QVERIFY(!sub.isVisible());
QTest::mouseRelease(menuWindow, Qt::LeftButton, {}, menu.rect().center() - QPoint(0, 2), 300);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
}
#endif
@@ -1588,6 +1585,54 @@ void tst_QMenu::widgetActionTriggerClosesMenu()
QCOMPARE(actionTriggered, &widgetAction);
}
+void tst_QMenu::transientParent()
+{
+ QMainWindow window;
+ window.resize(480, 320);
+ window.menuBar()->setNativeMenuBar(false);
+ centerOnScreen(&window);
+
+ QMenu *fileMenu = new QMenu("&File");
+ QAction *exitAct = new QAction("Exit");
+ fileMenu->addAction(exitAct);
+
+ QMenu *editMenu = new QMenu("&Edit");
+ QAction *undoAct = new QAction("Undo");
+ editMenu->addAction(undoAct);
+
+ QMenuBar *menuBar = new QMenuBar;
+ menuBar->addMenu(fileMenu);
+ menuBar->addMenu(editMenu);
+ window.setMenuBar(menuBar);
+
+ // On Mac, we need to create native key events to test menu
+ // action activation, so skip this part of the test.
+#if QT_CONFIG(shortcut) && !defined(Q_OS_DARWIN)
+ window.show();
+ QVERIFY(QTest::qWaitForWindowActive(&window));
+ QWindow *topLevel = window.windowHandle();
+ QVERIFY(topLevel);
+
+ QApplicationPrivate::setActiveWindow(&window);
+ window.setFocus();
+ QVERIFY(QTest::qWaitForWindowActive(&window));
+ QVERIFY(window.hasFocus());
+
+ QTest::keyPress(&window, Qt::Key_F, Qt::AltModifier);
+ QTRY_VERIFY(QTest::qWaitForWindowExposed(fileMenu));
+ if (fileMenu->isWindow() && fileMenu->window() && fileMenu->window()->windowHandle())
+ QVERIFY(fileMenu->window()->windowHandle()->transientParent());
+ QTest::keyRelease(fileMenu, Qt::Key_F, Qt::AltModifier);
+
+ QTest::keyPress(fileMenu, Qt::Key_E, Qt::AltModifier);
+ QTRY_VERIFY(QTest::qWaitForWindowExposed(editMenu));
+ if (editMenu->isWindow() && editMenu->window() && editMenu->window()->windowHandle())
+ QVERIFY(editMenu->window()->windowHandle()->transientParent());
+ QTest::keyRelease(editMenu, Qt::Key_E, Qt::AltModifier);
+#endif // QT_CONFIG(shortcut) && !Q_OS_DARWIN
+
+}
+
class MyMenu : public QMenu
{
Q_OBJECT
@@ -1803,12 +1848,12 @@ void tst_QMenu::menuSize_Scrolling()
private:
void showEvent(QShowEvent *e) override
{
- QVERIFY(actions().length() == m_numItems);
+ QVERIFY(actions().size() == m_numItems);
int hmargin = style()->pixelMetric(QStyle::PM_MenuHMargin, nullptr, this);
int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, nullptr, this);
const QMargins cm = contentsMargins();
- QRect lastItem = actionGeometry(actions().at(actions().length() - 1));
+ QRect lastItem = actionGeometry(actions().at(actions().size() - 1));
QSize s = size();
if (!QGuiApplication::platformName().compare(QLatin1String("minimal"), Qt::CaseInsensitive)
|| !QGuiApplication::platformName().compare(QLatin1String("offscreen"), Qt::CaseInsensitive)) {
@@ -1874,7 +1919,7 @@ void tst_QMenu::menuSize_Scrolling()
QVERIFY(QTest::qWaitForWindowExposed(&menu));
QList<QAction *> actions = menu.actions();
- QCOMPARE(actions.length(), numItems);
+ QCOMPARE(actions.size(), numItems);
MenuMetrics mm(&menu);
QTest::keyClick(&menu, Qt::Key_Home);
@@ -1954,11 +1999,11 @@ void tst_QMenu::QTBUG_61039_menu_shortcuts()
QSignalSpy actionKamenSpy(actionKamen, &QAction::triggered);
QTest::keyClick(&widget, Qt::Key_K);
- QTRY_COMPARE(actionKamenSpy.count(), 1);
+ QTRY_COMPARE(actionKamenSpy.size(), 1);
QSignalSpy actionJoeSpy(actionJoe, &QAction::triggered);
QTest::keyClick(&widget, Qt::Key_J, Qt::ControlModifier);
- QTRY_COMPARE(actionJoeSpy.count(), 1);
+ QTRY_COMPARE(actionJoeSpy.size(), 1);
}
void tst_QMenu::screenOrientationChangedCloseMenu()
@@ -1976,5 +2021,99 @@ void tst_QMenu::screenOrientationChangedCloseMenu()
QTRY_COMPARE(menu.isVisible(),false);
}
+/*
+ Verify that deleting the menu in a slot connected to an
+ action's triggered signal doesn't crash.
+ QTBUG-106718
+*/
+void tst_QMenu::deleteWhenTriggered()
+{
+ QPointer<QMenu> menu = new QMenu;
+ QAction *action = menu->addAction("Action", [&menu]{
+ delete menu;
+ });
+ menu->popup(QGuiApplication::primaryScreen()->availableGeometry().center());
+ menu->setActiveAction(action);
+ QTest::keyClick(menu, Qt::Key_Return);
+ QTRY_VERIFY(!menu);
+}
+
+/*
+ QMenu uses the caused-stack to create the parent/child relationship
+ for tear-off menus. Since QTornOffMenu set the DeleteOnClose flag, closing a
+ tear-off in the parent chain will result in a null-pointer in the caused-stack.
+ Verify that we don't crash when traversing the chain, as reported in QTBUG-112217.
+
+ The test has to open the submenus by hovering of the menu action, otherwise
+ the caused-stack remains empty and the issue doesn't reproduce. Due to QMenu's
+ timing and "sloppiness", we need to move the mouse within the action, with some
+ waiting and event processing in between to trigger the opening of the submenu.
+ If this fails we skip, as we then can't test what we are trying to test.
+*/
+void tst_QMenu::nestedTearOffDetached()
+{
+ // Since QTornOffMenu is not declared in qmenuprivate.h we can't access the
+ // object even through QMenuPrivate. So use an event filter to watch out for
+ // a QTornOffMenu showing.
+ class TearOffWatcher : public QObject
+ {
+ public:
+ QMenu *tornOffMenu = nullptr;
+ protected:
+ bool eventFilter(QObject *receiver, QEvent *event) override
+ {
+ if (event->type() == QEvent::Show && receiver->inherits("QTornOffMenu"))
+ tornOffMenu = qobject_cast<QMenu *>(receiver);
+ return QObject::eventFilter(receiver, event);
+ }
+ } watcher;
+ qApp->installEventFilter(&watcher);
+
+ QWidget widget;
+ QMenu *menu = new QMenu("Context", &widget);
+
+ MenuMetrics mm(menu);
+ const int tearOffOffset = mm.fw + mm.vmargin + mm.tearOffHeight / 2;
+
+ QMenu *subMenu = menu->addMenu("SubMenu");
+ menu->setTearOffEnabled(true);
+ QMenu *subSubMenu = subMenu->addMenu("SubSubMenu");
+ subMenu->setTearOffEnabled(true);
+ subSubMenu->addAction("Action!");
+ subSubMenu->setTearOffEnabled(true);
+
+ widget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&widget));
+
+ // open and tear off context menu
+ menu->popup(widget.geometry().center());
+ QTest::mouseClick(menu, Qt::LeftButton, {}, QPoint(menu->width() / 2, tearOffOffset));
+
+ QMenu *menuTorn = watcher.tornOffMenu;
+ watcher.tornOffMenu = nullptr;
+ QVERIFY(menuTorn);
+ QVERIFY(QTest::qWaitForWindowExposed(menuTorn));
+
+ // open second menu and tear-off
+ QTest::mouseMove(menuTorn, menuTorn->actionGeometry(subMenu->menuAction()).topLeft());
+ QTest::qWait(100);
+ QTest::mouseMove(menuTorn, menuTorn->actionGeometry(subMenu->menuAction()).center());
+ if (!QTest::qWaitFor([subMenu]{ return subMenu->isVisible(); }))
+ QSKIP("Menu failed to show, skipping test");
+
+ QTest::mouseClick(subMenu, Qt::LeftButton, {}, QPoint(subMenu->width() / 2, tearOffOffset));
+ menuTorn = watcher.tornOffMenu;
+ QVERIFY(menuTorn);
+ QVERIFY(QTest::qWaitForWindowExposed(menuTorn));
+ // close the top level tear off
+ menu->hideTearOffMenu();
+ // open third menu and tear-off
+ QTest::mouseMove(menuTorn, menuTorn->actionGeometry(subSubMenu->menuAction()).topLeft());
+ QTest::qWait(100);
+ QTest::mouseMove(menuTorn, menuTorn->actionGeometry(subSubMenu->menuAction()).center());
+ QTRY_VERIFY(subSubMenu->isVisible());
+ QTest::mouseClick(subSubMenu, Qt::LeftButton, {}, QPoint(subSubMenu->width() / 2, tearOffOffset));
+}
+
QTEST_MAIN(tst_QMenu)
#include "tst_qmenu.moc"
diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu_mac.mm b/tests/auto/widgets/widgets/qmenu/tst_qmenu_mac.mm
index f90af47c19..ba76c28fd4 100644
--- a/tests/auto/widgets/widgets/qmenu/tst_qmenu_mac.mm
+++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu_mac.mm
@@ -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
#import <AppKit/AppKit.h>
diff --git a/tests/auto/widgets/widgets/qmenubar/BLACKLIST b/tests/auto/widgets/widgets/qmenubar/BLACKLIST
index 633bda332f..516fd39f86 100644
--- a/tests/auto/widgets/widgets/qmenubar/BLACKLIST
+++ b/tests/auto/widgets/widgets/qmenubar/BLACKLIST
@@ -1,10 +1,5 @@
[check_menuPosition]
-ubuntu-16.04
-#QTBUG-66255
-ubuntu-18.04
-ubuntu-20.04
-[activatedCount]
-opensuse-42.3
+ubuntu-22.04
# QTBUG-87421
[cornerWidgets]
android
diff --git a/tests/auto/widgets/widgets/qmenubar/CMakeLists.txt b/tests/auto/widgets/widgets/qmenubar/CMakeLists.txt
index 63f690a2ed..f2b1c1bec6 100644
--- a/tests/auto/widgets/widgets/qmenubar/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qmenubar/CMakeLists.txt
@@ -1,16 +1,24 @@
-# Generated from qmenubar.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qmenubar Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmenubar LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qmenubar
SOURCES
tst_qmenubar.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::TestPrivate
Qt::Widgets
+ Qt::WidgetsPrivate
)
## Scopes:
@@ -19,6 +27,6 @@ qt_internal_add_test(tst_qmenubar
qt_internal_extend_target(tst_qmenubar CONDITION MACOS
SOURCES
tst_qmenubar_mac.mm
- PUBLIC_LIBRARIES
+ LIBRARIES
${FWAppKit}
)
diff --git a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
index 1b8de0b75c..8524b4212c 100644
--- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
+++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.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>
@@ -40,10 +15,13 @@
#include <QVBoxLayout>
#include <QLabel>
#include <QPlainTextEdit>
+#include <QTranslator>
#include <qscreen.h>
#include <qobject.h>
+#include <QtWidgets/private/qapplication_p.h>
+
QT_FORWARD_DECLARE_CLASS(QMainWindow)
#include <qmenubar.h>
@@ -115,13 +93,6 @@ private slots:
#endif
void allowActiveAndDisabled();
void taskQTBUG56860_focus();
- void check_endKey();
- void check_homeKey();
-
-// void check_mouse1_data();
-// void check_mouse1();
-// void check_mouse2_data();
-// void check_mouse2();
void check_altPress();
void check_altClosePress();
@@ -144,6 +115,8 @@ private slots:
#ifdef Q_OS_MACOS
void taskQTBUG56275_reinsertMenuInParentlessQMenuBar();
void QTBUG_57404_existingMenuItemException();
+ void defaultEditMenuItems();
+
#endif
void QTBUG_25669_menubarActionDoubleTriggered();
void taskQTBUG55966_subMenuRemoved();
@@ -356,7 +329,7 @@ void tst_QMenuBar::accel()
QMainWindow w;
const TestMenu menu = initWindowWithSimpleMenuBar(w);
w.show();
- QApplication::setActiveWindow(&w);
+ QApplicationPrivate::setActiveWindow(&w);
QVERIFY(QTest::qWaitForWindowActive(&w));
// shortcuts won't work unless the window is active
QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_A, Qt::ControlModifier );
@@ -378,7 +351,7 @@ void tst_QMenuBar::activatedCount()
QFETCH( bool, forceNonNative );
initWindowWithSimpleMenuBar(w, forceNonNative);
w.show();
- QApplication::setActiveWindow(&w);
+ QApplicationPrivate::setActiveWindow(&w);
QVERIFY(QTest::qWaitForWindowActive(&w));
QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_A, Qt::ControlModifier );
@@ -578,7 +551,7 @@ void tst_QMenuBar::check_accelKeys()
QMainWindow w;
initWindowWithComplexMenuBar(w);
w.show();
- QApplication::setActiveWindow(&w);
+ QApplicationPrivate::setActiveWindow(&w);
QVERIFY(QTest::qWaitForWindowActive(&w));
// start with a bogus key that shouldn't trigger anything
@@ -657,7 +630,7 @@ void tst_QMenuBar::check_cursorKeys1()
QMainWindow w;
initWindowWithComplexMenuBar(w);
w.show();
- QApplication::setActiveWindow(&w);
+ QApplicationPrivate::setActiveWindow(&w);
QVERIFY(QTest::qWaitForWindowActive(&w));
// start with a ALT + 1 that activates the first popupmenu
@@ -697,7 +670,7 @@ void tst_QMenuBar::check_cursorKeys2()
QMainWindow w;
initWindowWithComplexMenuBar(w);
w.show();
- QApplication::setActiveWindow(&w);
+ QApplicationPrivate::setActiveWindow(&w);
QVERIFY(QTest::qWaitForWindowActive(&w));
// select popupmenu2
@@ -736,7 +709,7 @@ void tst_QMenuBar::check_cursorKeys3()
QMainWindow w;
initWindowWithComplexMenuBar(w);
w.show();
- QApplication::setActiveWindow(&w);
+ QApplicationPrivate::setActiveWindow(&w);
QVERIFY(QTest::qWaitForWindowActive(&w));
// select Popupmenu 2
@@ -778,7 +751,7 @@ void tst_QMenuBar::taskQTBUG56860_focus()
w.setCentralWidget(e);
w.show();
- QApplication::setActiveWindow(&w);
+ QApplicationPrivate::setActiveWindow(&w);
QVERIFY(QTest::qWaitForWindowActive(&w));
QTRY_COMPARE(QApplication::focusWidget(), e);
@@ -805,85 +778,6 @@ void tst_QMenuBar::taskQTBUG56860_focus()
}
/*!
- If a popupmenu is active you can use home to go quickly to the first item in the menu.
-*/
-void tst_QMenuBar::check_homeKey()
-{
- // I'm temporarily shutting up this testcase.
- // Seems like the behaviour i'm expecting isn't ok.
- QSKIP("This test has been \"temporarily\" disabled at least since 2009 :)");
-
- QEXPECT_FAIL( "0", "Popupmenu should respond to a Home key", Abort );
-
- QMainWindow w;
- initWindowWithComplexMenuBar(w);
- w.show();
- QApplication::setActiveWindow(&w);
- QVERIFY(QTest::qWaitForWindowActive(&w));
-
- // select Popupmenu 2
- QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_2, Qt::AltModifier );
-
- // Simulate some keys
- QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Down );
- QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Down );
- QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Down );
- QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Home );
- // and press ENTER
- QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Enter );
- // Let's see if the correct slot is called...
-// QVERIFY2( m_complexActionTriggerCount[int('c')] == 1, "Popupmenu should respond to a Home key" );
- QCOMPARE(m_complexTriggerCount[int('c')], 1);
- QCOMPARE(m_complexTriggerCount[3], 0);
- QCOMPARE(m_complexTriggerCount[4], 0);
- QCOMPARE(m_complexTriggerCount[int('a')], 0);
- QCOMPARE(m_complexTriggerCount[int('b')], 0);
- QCOMPARE(m_complexTriggerCount[int('d')], 0);
- QCOMPARE(m_complexTriggerCount[int('e')], 0);
- QCOMPARE(m_complexTriggerCount[int('f')], 0);
- QCOMPARE(m_complexTriggerCount[int('g')], 0);
- QCOMPARE(m_complexTriggerCount[int('h')], 0);
-}
-
-/*!
- If a popupmenu is active you can use end to go quickly to the last item in the menu.
-*/
-void tst_QMenuBar::check_endKey()
-{
- // I'm temporarily silenting this testcase.
- // Seems like the behaviour i'm expecting isn't ok.
- QSKIP("This test has been \"temporarily\" disabled at least since 2009 :)");
-
- QEXPECT_FAIL( "0", "Popupmenu should respond to an End key", Abort );
-
- QMainWindow w;
- initWindowWithComplexMenuBar(w);
- w.show();
- QApplication::setActiveWindow(&w);
- QVERIFY(QTest::qWaitForWindowActive(&w));
-
- // select Popupmenu 2
- QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_2, Qt::AltModifier );
-
- // Simulate some keys
- QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_End );
- // and press ENTER
- QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Enter );
- // Let's see if the correct slot is called...
-// QVERIFY2( m_complexActionTriggerCount[int('h')] == 1, "Popupmenu should respond to an End key" );
- QCOMPARE(m_complexTriggerCount[int('h')], 1);//, "Popupmenu should respond to an End key");
- QCOMPARE(m_complexTriggerCount[3], 0);
- QCOMPARE(m_complexTriggerCount[4], 0);
- QCOMPARE(m_complexTriggerCount[int('a')], 0);
- QCOMPARE(m_complexTriggerCount[int('b')], 0);
- QCOMPARE(m_complexTriggerCount[int('c')], 0);
- QCOMPARE(m_complexTriggerCount[int('d')], 0);
- QCOMPARE(m_complexTriggerCount[int('e')], 0);
- QCOMPARE(m_complexTriggerCount[int('f')], 0);
- QCOMPARE(m_complexTriggerCount[int('g')], 0);
-}
-
-/*!
If a popupmenu is active you can use esc to hide the menu and then the
menubar should become active.
If Down is pressed next the popup is activated again.
@@ -900,7 +794,7 @@ void tst_QMenuBar::check_escKey()
const TestMenu menu = initWindowWithComplexMenuBar(w);
w.show();
w.setFocus();
- QApplication::setActiveWindow(&w);
+ QApplicationPrivate::setActiveWindow(&w);
QVERIFY(QTest::qWaitForWindowActive(&w));
QVERIFY( !menu.menus.at(0)->isActiveWindow() );
@@ -938,112 +832,6 @@ void tst_QMenuBar::check_escKey()
#endif
-// void tst_QMenuBar::check_mouse1_data()
-// {
-// QTest::addColumn<QString>("popup_item");
-// QTest::addColumn<int>("itemA_count");
-// QTest::addColumn<int>("itemB_count");
-
-// QTest::newRow( "A" ) << QString( "Item A Ctrl+A" ) << 1 << 0;
-// QTest::newRow( "B" ) << QString( "Item B Ctrl+B" ) << 0 << 1;
-// }
-
-// /*!
-// Check if the correct signals are emitted if we select a popupmenu.
-// */
-// void tst_QMenuBar::check_mouse1()
-// {
-// if (QSystem::curStyle() == "Motif")
-// QSKIP("This fails in Motif due to a bug in the testing framework");
-// QFETCH( QString, popup_item );
-// QFETCH( int, itemA_count );
-// QFETCH( int, itemB_count );
-
-// // initComplexMenubar();
-// QVERIFY( !pm1->isActiveWindow() );
-// QVERIFY( !pm2->isActiveWindow() );
-
-// QTest::qWait(1000);
-// QtTestMouse mouse;
-// mouse.mouseEvent( QtTestMouse::MouseClick, mb, "Menu &1", Qt::LeftButton );
-
-// QVERIFY( pm1->isActiveWindow() );
-// QVERIFY( !pm2->isActiveWindow() );
-
-// QTest::qWait(1000);
-// mouse.mouseEvent( QtTestMouse::MouseClick, pm1, popup_item, Qt::LeftButton );
-
-// QCOMPARE(m_complexActionTriggerCount[3], 0);
-// QCOMPARE(m_complexActionTriggerCount[4], 0);
-// QCOMPARE(m_complexActionTriggerCount['a'], (uint)itemA_count); // this option should have fired
-// QCOMPARE(m_complexActionTriggerCount['b'], (uint)itemB_count);
-// QCOMPARE(m_complexActionTriggerCount['c'], 0);
-// QCOMPARE(m_complexActionTriggerCount['d'], 0);
-// QCOMPARE(m_complexActionTriggerCount['e'], 0);
-// QCOMPARE(m_complexActionTriggerCount['f'], 0);
-// QCOMPARE(m_complexActionTriggerCount['g'], 0);
-// }
-
-// void tst_QMenuBar::check_mouse2_data()
-// {
-// QTest::addColumn<QString>("label");
-// QTest::addColumn<int>("itemA_count");
-// QTest::addColumn<int>("itemB_count");
-// QTest::addColumn<int>("itemC_count");
-// QTest::addColumn<int>("itemD_count");
-// QTest::addColumn<int>("itemE_count");
-// QTest::addColumn<int>("itemF_count");
-// QTest::addColumn<int>("itemG_count");
-// QTest::addColumn<int>("itemH_count");
-// QTest::addColumn<int>("menu3_count");
-
-// QTest::newRow( "A" ) << QString( "Menu &1/Item A Ctrl+A" ) << 1 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0;
-// QTest::newRow( "B" ) << QString( "Menu &1/Item B Ctrl+B" ) << 0 << 1 << 0 << 0 << 0 << 0 << 0 << 0 << 0;
-// QTest::newRow( "C" ) << QString( "Menu &2/Item C Ctrl+C" ) << 0 << 0 << 1 << 0 << 0 << 0 << 0 << 0 << 0;
-// QTest::newRow( "D" ) << QString( "Menu &2/Item D Ctrl+D" ) << 0 << 0 << 0 << 1 << 0 << 0 << 0 << 0 << 0;
-// QTest::newRow( "E" ) << QString( "Menu &2/Item E Ctrl+E" ) << 0 << 0 << 0 << 0 << 1 << 0 << 0 << 0 << 0;
-// QTest::newRow( "F" ) << QString( "Menu &2/Item F Ctrl+F" ) << 0 << 0 << 0 << 0 << 0 << 1 << 0 << 0 << 0;
-// QTest::newRow( "G" ) << QString( "Menu &2/Item G Ctrl+G" ) << 0 << 0 << 0 << 0 << 0 << 0 << 1 << 0 << 0;
-// QTest::newRow( "H" ) << QString( "Menu &2/Item H Ctrl+H" ) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 1 << 0;
-// QTest::newRow( "menu 3" ) << QString( "M&enu 3" ) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 1;
-// }
-
-// /*!
-// Check if the correct signals are emitted if we select a popupmenu.
-// This time, we use a little bit more magic from the testframework.
-// */
-// void tst_QMenuBar::check_mouse2()
-// {
-// if (QSystem::curStyle() == "Motif")
-// QSKIP("This fails in Motif due to a bug in the testing framework");
-// QFETCH( QString, label );
-// QFETCH( int, itemA_count );
-// QFETCH( int, itemB_count );
-// QFETCH( int, itemC_count );
-// QFETCH( int, itemD_count );
-// QFETCH( int, itemE_count );
-// QFETCH( int, itemF_count );
-// QFETCH( int, itemG_count );
-// QFETCH( int, itemH_count );
-// QFETCH( int, menu3_count );
-
-// // initComplexMenubar();
-// QtTestMouse mouse;
-// mouse.click( QtTestMouse::Menu, label, Qt::LeftButton );
-
-// // check if the correct signals have fired
-// QCOMPARE(m_complexActionTriggerCount[3], (uint)menu3_count);
-// QCOMPARE(m_complexActionTriggerCount[4], 0);
-// QCOMPARE(m_complexActionTriggerCount['a'], (uint)itemA_count);
-// QCOMPARE(m_complexActionTriggerCount['b'], (uint)itemB_count);
-// QCOMPARE(m_complexActionTriggerCount['c'], (uint)itemC_count);
-// QCOMPARE(m_complexActionTriggerCount['d'], (uint)itemD_count);
-// QCOMPARE(m_complexActionTriggerCount['e'], (uint)itemE_count);
-// QCOMPARE(m_complexActionTriggerCount['f'], (uint)itemF_count);
-// QCOMPARE(m_complexActionTriggerCount['g'], (uint)itemG_count);
-// QCOMPARE(m_complexActionTriggerCount['h'], (uint)itemH_count);
-// }
-
void tst_QMenuBar::allowActiveAndDisabled()
{
QMenuBar menuBar;
@@ -1098,7 +886,7 @@ void tst_QMenuBar::check_altPress()
initWindowWithSimpleMenuBar(w);
w.show();
w.setFocus();
- QApplication::setActiveWindow(&w);
+ QApplicationPrivate::setActiveWindow(&w);
QVERIFY(QTest::qWaitForWindowActive(&w));
QTest::keyClick( &w, Qt::Key_Alt );
@@ -1128,7 +916,7 @@ void tst_QMenuBar::check_altClosePress()
w.show();
w.move(QGuiApplication::primaryScreen()->availableGeometry().center());
- QApplication::setActiveWindow(&w);
+ QApplicationPrivate::setActiveWindow(&w);
QVERIFY(QTest::qWaitForWindowActive(&w));
QTest::keyClick(&w, Qt::Key_F, Qt::AltModifier);
@@ -1149,7 +937,7 @@ void tst_QMenuBar::check_shortcutPress()
const TestMenu menu = initWindowWithComplexMenuBar(w);
w.show();
w.setFocus();
- QApplication::setActiveWindow(&w);
+ QApplicationPrivate::setActiveWindow(&w);
QVERIFY(QTest::qWaitForWindowActive(&w));
QCOMPARE(m_complexTriggerCount[3], 0);
@@ -1206,7 +994,7 @@ void tst_QMenuBar::check_menuPosition()
QAction *menu_action = w.menuBar()->addMenu(&menu);
centerOnScreen(&w);
w.show();
- qApp->setActiveWindow(&w);
+ QApplicationPrivate::setActiveWindow(&w);
QVERIFY(QTest::qWaitForWindowActive(&w));
//the menu should be below the menubar item
@@ -1290,9 +1078,9 @@ void tst_QMenuBar::task223138_triggered()
//let's trigger the first action
top->trigger();
- QCOMPARE(menubarSpy.count(), 1);
- QCOMPARE(menuSpy.count(), 1);
- QCOMPARE(submenuSpy.count(), 0);
+ QCOMPARE(menubarSpy.size(), 1);
+ QCOMPARE(menuSpy.size(), 1);
+ QCOMPARE(submenuSpy.size(), 0);
menubarSpy.clear();
menuSpy.clear();
@@ -1300,9 +1088,9 @@ void tst_QMenuBar::task223138_triggered()
//let's trigger the sub action
action->trigger();
- QCOMPARE(menubarSpy.count(), 1);
- QCOMPARE(menuSpy.count(), 1);
- QCOMPARE(submenuSpy.count(), 1);
+ QCOMPARE(menubarSpy.size(), 1);
+ QCOMPARE(menuSpy.size(), 1);
+ QCOMPARE(submenuSpy.size(), 1);
}
void tst_QMenuBar::task256322_highlight()
@@ -1325,7 +1113,7 @@ void tst_QMenuBar::task256322_highlight()
centerOnScreen(&win);
win.show();
- QApplication::setActiveWindow(&win);
+ QApplicationPrivate::setActiveWindow(&win);
QVERIFY(QTest::qWaitForWindowActive(&win));
const QPoint filePos = menuBarActionWindowPos(win.menuBar(), file);
@@ -1381,8 +1169,8 @@ void tst_QMenuBar::menubarSizeHint()
mb.setStyle(&style);
//this is a list of arbitrary strings so that we check the geometry
- QStringList list = QStringList() << "trer" << "ezrfgtgvqd" << "sdgzgzerzerzer" << "eerzertz" << "er";
- foreach(QString str, list)
+ const auto list = QStringList{"trer", "ezrfgtgvqd", "sdgzgzerzerzer", "eerzertz", "er"};
+ for (const QString &str : list)
mb.addAction(str);
const int panelWidth = style.pixelMetric(QStyle::PM_MenuBarPanelWidth);
@@ -1393,7 +1181,8 @@ void tst_QMenuBar::menubarSizeHint()
centerOnScreen(&mb);
mb.show();
QRect result;
- foreach(QAction *action, mb.actions()) {
+ const auto actions = mb.actions();
+ for (QAction *action : actions) {
const QRect actionRect = mb.actionGeometry(action);
if (!result.isNull()) //this is the first item
QCOMPARE(actionRect.left() - result.right() - 1, spacing);
@@ -1429,11 +1218,11 @@ void tst_QMenuBar::taskQTBUG4965_escapeEaten()
QMenu menu("menu1");
QAction *first = menubar.addMenu(&menu);
#if QT_CONFIG(shortcut)
- menu.addAction("quit", &menubar, SLOT(close()), QKeySequence("ESC"));
+ menu.addAction("quit", QKeySequence("ESC"), &menubar, SLOT(close()));
#endif
centerOnScreen(&menubar);
menubar.show();
- QApplication::setActiveWindow(&menubar);
+ QApplicationPrivate::setActiveWindow(&menubar);
QVERIFY(QTest::qWaitForWindowExposed(&menubar));
menubar.setActiveAction(first);
QTRY_VERIFY(menu.isVisible());
@@ -1464,7 +1253,7 @@ void tst_QMenuBar::taskQTBUG11823_crashwithInvisibleActions()
centerOnScreen(&menubar);
menubar.show();
- QApplication::setActiveWindow(&menubar);
+ QApplicationPrivate::setActiveWindow(&menubar);
QVERIFY(QTest::qWaitForWindowActive(&menubar));
menubar.setActiveAction(m);
QCOMPARE(menubar.activeAction(), m);
@@ -1495,7 +1284,7 @@ void tst_QMenuBar::closeOnSecondClickAndOpenOnThirdClick() // QTBUG-32807, menu
QMenu *fileMenu = menuBar->addMenu(QStringLiteral("OpenCloseOpen"));
fileMenu->addAction(QStringLiteral("Quit"));
mainWindow.show();
- QApplication::setActiveWindow(&mainWindow);
+ QApplicationPrivate::setActiveWindow(&mainWindow);
QVERIFY(QTest::qWaitForWindowActive(&mainWindow));
const QPoint center = menuBarActionWindowPos(mainWindow.menuBar(), fileMenu->menuAction());
@@ -1590,7 +1379,7 @@ void tst_QMenuBar::taskQTBUG53205_crashReparentNested()
mainWindow.resize(300, 200);
centerOnScreen(&mainWindow);
const TestMenu testMenus = initWindowWithComplexMenuBar(mainWindow);
- QApplication::setActiveWindow(&mainWindow);
+ QApplicationPrivate::setActiveWindow(&mainWindow);
// they can't be windows
QWidget hiddenParent(&mainWindow, {});
@@ -1640,12 +1429,12 @@ void tst_QMenuBar::QTBUG_65488_hiddenActionTriggered()
// resize to action's size to make Action1 hidden
win.resize(actRect.width() - 10, win.size().height());
win.show();
- QApplication::setActiveWindow(&win);
+ QApplicationPrivate::setActiveWindow(&win);
QVERIFY(QTest::qWaitForWindowExposed(&win));
// click center of the blank area on the menubar where Action1 resided
QTest::mouseClick(win.windowHandle(), Qt::LeftButton, Qt::NoModifier, win.menuBar()->geometry().center());
QCoreApplication::sendPostedEvents(); // make sure all queued events also dispatched
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
}
// QTBUG-56526
@@ -1712,20 +1501,20 @@ void tst_QMenuBar::QTBUG_25669_menubarActionDoubleTriggered()
QSignalSpy spy(win.menuBar(), &QMenuBar::triggered);
win.show();
- QApplication::setActiveWindow(&win);
+ QApplicationPrivate::setActiveWindow(&win);
QVERIFY(QTest::qWaitForWindowExposed(&win));
QPoint posAct1 = menuBarActionWindowPos(win.menuBar(), act1);
QPoint posAct2 = menuBarActionWindowPos(win.menuBar(), act2);
QTest::mouseClick(win.windowHandle(), Qt::LeftButton, Qt::NoModifier, posAct1);
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QTest::mouseClick(win.windowHandle(), Qt::LeftButton, Qt::NoModifier, posAct2);
- QTRY_COMPARE(spy.count(), 2);
+ QTRY_COMPARE(spy.size(), 2);
QTest::mouseClick(win.windowHandle(), Qt::LeftButton, Qt::NoModifier, posAct2);
- QTRY_COMPARE(spy.count(), 3);
+ QTRY_COMPARE(spy.size(), 3);
}
void tst_QMenuBar::slotForTaskQTBUG53205()
@@ -1749,7 +1538,7 @@ void tst_QMenuBar::taskQTBUG46812_doNotLeaveMenubarHighlighted()
initWindowWithSimpleMenuBar(mainWindow);
mainWindow.show();
- QApplication::setActiveWindow(&mainWindow);
+ QApplicationPrivate::setActiveWindow(&mainWindow);
QVERIFY(QTest::qWaitForWindowActive(&mainWindow));
QVERIFY(!mainWindow.menuBar()->hasFocus());
@@ -1818,6 +1607,32 @@ void tst_QMenuBar::QTBUG_57404_existingMenuItemException()
QTest::qWait(100);
// No crash, all fine. Ideally, there should be only one warning.
}
+
+void tst_QMenuBar::defaultEditMenuItems()
+{
+ class TestTranslator : public QTranslator
+ {
+ public:
+ QString translate(const char *context, const char *sourceText,
+ const char *disambiguation = nullptr, int n = -1) const override
+ {
+ if (QByteArrayView(context) == "QCocoaMenu" && QByteArrayView(sourceText) == "Edit")
+ return QString("Editieren");
+ return QTranslator::translate(context, sourceText, disambiguation, n);
+ }
+ } testTranslator;
+ qApp->installTranslator(&testTranslator);
+
+ QMainWindow mw;
+ mw.show();
+ QVERIFY(QTest::qWaitForWindowActive(&mw));
+
+ mw.menuBar()->addMenu("Editieren")->addAction("Undo");
+
+ mw.hide();
+ mw.show();
+ // this should not crash with infinite recursion
+}
#endif // Q_OS_MACOS
void tst_QMenuBar::taskQTBUG55966_subMenuRemoved()
@@ -1835,7 +1650,7 @@ void tst_QMenuBar::taskQTBUG55966_subMenuRemoved()
delete subMenu;
window.show();
- QApplication::setActiveWindow(&window);
+ QApplicationPrivate::setActiveWindow(&window);
QVERIFY(QTest::qWaitForWindowActive(&window));
QTest::qWait(500);
}
diff --git a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar_mac.mm b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar_mac.mm
index 823ca7edfa..55e983a4d1 100644
--- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar_mac.mm
+++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar_mac.mm
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 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) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#import <Cocoa/Cocoa.h>
diff --git a/tests/auto/widgets/widgets/qopenglwidget/BLACKLIST b/tests/auto/widgets/widgets/qopenglwidget/BLACKLIST
index ecb962d8ca..6b96499889 100644
--- a/tests/auto/widgets/widgets/qopenglwidget/BLACKLIST
+++ b/tests/auto/widgets/widgets/qopenglwidget/BLACKLIST
@@ -1,5 +1,7 @@
-[stackWidgetOpaqueChildIsVisible]
-windows-10 msvc-2017
+# Temporary solution COIN-966
+ubuntu
+rhel
+opensuse-leap
# QTBUG-87436
[clearAndGrab]
diff --git a/tests/auto/widgets/widgets/qopenglwidget/CMakeLists.txt b/tests/auto/widgets/widgets/qopenglwidget/CMakeLists.txt
index f32b547329..78cef5300a 100644
--- a/tests/auto/widgets/widgets/qopenglwidget/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qopenglwidget/CMakeLists.txt
@@ -1,14 +1,21 @@
-# Generated from qopenglwidget.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qopenglwidget Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qopenglwidget LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qopenglwidget
- LOWDPI # special case
+ LOWDPI
SOURCES
tst_qopenglwidget.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::Gui
Qt::GuiPrivate
diff --git a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp
index 3d7bb36f24..773ccd894c 100644
--- a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp
+++ b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp
@@ -1,34 +1,10 @@
-/****************************************************************************
-**
-** 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 <QtOpenGLWidgets/QOpenGLWidget>
#include <QtGui/QOpenGLFunctions>
#include <QtGui/QPainter>
+#include <QtGui/QBackingStore>
#include <QtGui/QScreen>
#include <QtGui/QStaticText>
#include <QtWidgets/QGraphicsView>
@@ -37,12 +13,18 @@
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QStackedWidget>
+#include <QtWidgets/QTabWidget>
+#include <QtWidgets/QLabel>
#include <QTest>
#include <QSignalSpy>
#include <private/qguiapplication_p.h>
#include <private/qstatictext_p.h>
#include <private/qopengltextureglyphcache_p.h>
#include <qpa/qplatformintegration.h>
+#include <private/qguiapplication_p.h>
+#include <qpa/qplatformbackingstore.h>
+#include <qpa/qplatformintegration.h>
+#include <rhi/qrhi.h>
class tst_QOpenGLWidget : public QObject
{
@@ -54,10 +36,14 @@ private slots:
void clearAndGrab();
void clearAndResizeAndGrab();
void createNonTopLevel();
+#if QT_CONFIG(egl)
+ void deviceLoss();
+#endif
void painter();
void reparentToAlreadyCreated();
void reparentToNotYetCreated();
void reparentHidden();
+ void reparentTopLevel();
void asViewport();
void requestUpdate();
void fboRedirect();
@@ -66,6 +52,9 @@ private slots:
void stackWidgetOpaqueChildIsVisible();
void offscreen();
void offscreenThenOnscreen();
+ void paintWhileHidden();
+ void widgetWindowColorFormat_data();
+ void widgetWindowColorFormat();
#ifdef QT_BUILD_INTERNAL
void staticTextDanglingPointer();
@@ -87,7 +76,7 @@ void tst_QOpenGLWidget::create()
QSignalSpy frameSwappedSpy(w.data(), SIGNAL(frameSwapped()));
w->show();
QVERIFY(QTest::qWaitForWindowExposed(w.data()));
- QVERIFY(frameSwappedSpy.count() > 0);
+ QVERIFY(frameSwappedSpy.size() > 0);
QVERIFY(w->isValid());
QVERIFY(w->context());
@@ -152,6 +141,9 @@ void tst_QOpenGLWidget::clearAndGrab()
void tst_QOpenGLWidget::clearAndResizeAndGrab()
{
+#ifdef Q_OS_ANDROID
+ QSKIP("Crashes on Android, figure out why (QTBUG-102043)");
+#endif
QScopedPointer<QOpenGLWidget> w(new ClearWidget(0, 640, 480));
w->resize(640, 480);
w->show();
@@ -179,7 +171,7 @@ void tst_QOpenGLWidget::createNonTopLevel()
w.resize(400, 400);
w.show();
QVERIFY(QTest::qWaitForWindowExposed(&w));
- QVERIFY(frameSwappedSpy.count() > 0);
+ QVERIFY(frameSwappedSpy.size() > 0);
QVERIFY(glw->m_resizeCalled);
glw->m_resizeCalled = false;
@@ -203,10 +195,49 @@ void tst_QOpenGLWidget::createNonTopLevel()
QVERIFY(QOpenGLContext::currentContext() == glw->context() && glw->context());
}
+#if QT_CONFIG(egl)
+void tst_QOpenGLWidget::deviceLoss()
+{
+ QScopedPointer<QOpenGLWidget> w(new ClearWidget(0, 640, 480));
+
+ w->resize(640, 480);
+ w->show();
+
+ auto rhi = w->backingStore()->handle()->rhi();
+ QNativeInterface::QEGLContext *rhiContext = nullptr;
+ if (rhi->backend() == QRhi::OpenGLES2) {
+ auto rhiHandles = static_cast<const QRhiGles2NativeHandles *>(rhi->nativeHandles());
+ rhiContext = rhiHandles->context->nativeInterface<QNativeInterface::QEGLContext>();
+ }
+ if (!rhiContext)
+ QSKIP("deviceLoss needs EGL");
+
+ QVERIFY(QTest::qWaitForWindowExposed(w.data()));
+
+ QImage image = w->grabFramebuffer();
+ QVERIFY(!image.isNull());
+ QCOMPARE(image.width(), w->width());
+ QCOMPARE(image.height(), w->height());
+ QVERIFY(image.pixel(30, 40) == qRgb(255, 0, 0));
+
+ rhiContext->invalidateContext();
+
+ w->resize(600, 600);
+ QSignalSpy frameSwappedSpy(w.get(), &QOpenGLWidget::resized);
+ QTRY_VERIFY(frameSwappedSpy.size() > 0);
+
+ image = w->grabFramebuffer();
+ QVERIFY(!image.isNull());
+ QCOMPARE(image.width(), w->width());
+ QCOMPARE(image.height(), w->height());
+ QVERIFY(image.pixel(30, 40) == qRgb(255, 0, 0));
+}
+#endif
+
class PainterWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
public:
- PainterWidget(QWidget *parent)
+ PainterWidget(QWidget *parent = nullptr)
: QOpenGLWidget(parent), m_clear(false) { }
void initializeGL() override {
@@ -272,6 +303,9 @@ void tst_QOpenGLWidget::reparentToAlreadyCreated()
void tst_QOpenGLWidget::reparentToNotYetCreated()
{
+#ifdef Q_OS_ANDROID
+ QSKIP("Crashes on Android, figure out why (QTBUG-102043)");
+#endif
QWidget w1;
PainterWidget *glw = new PainterWidget(&w1);
w1.resize(640, 480);
@@ -320,6 +354,70 @@ void tst_QOpenGLWidget::reparentHidden()
QVERIFY(originalContext != newContext);
}
+void tst_QOpenGLWidget::reparentTopLevel()
+{
+#ifdef Q_OS_ANDROID
+ QSKIP("Crashes on Android, figure out why (QTBUG-102043)");
+#endif
+ // no GL content yet, just an ordinary tab widget, top-level
+ QTabWidget tabWidget;
+ tabWidget.resize(640, 480);
+ tabWidget.addTab(new QLabel("Dummy page"), "Page 1");
+ tabWidget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&tabWidget));
+
+ PainterWidget *glw1 = new PainterWidget;
+ // add child GL widget as a tab page
+ {
+ QSignalSpy frameSwappedSpy(glw1, &QOpenGLWidget::frameSwapped);
+ tabWidget.setCurrentIndex(tabWidget.addTab(glw1, "OpenGL widget 1"));
+ QTRY_VERIFY(frameSwappedSpy.size() > 0);
+ }
+
+ PainterWidget *glw2 = new PainterWidget;
+ // add child GL widget #2 as a tab page
+ {
+ QSignalSpy frameSwappedSpy(glw2, &QOpenGLWidget::frameSwapped);
+ tabWidget.setCurrentIndex(tabWidget.addTab(glw2, "OpenGL widget 2"));
+ QTRY_VERIFY(frameSwappedSpy.size() > 0);
+ }
+
+ QImage image = glw2->grabFramebuffer();
+ QVERIFY(image.pixel(20, 10) == qRgb(0, 0, 255));
+
+ // now delete GL widget #2
+ {
+ QSignalSpy frameSwappedSpy(glw1, &QOpenGLWidget::frameSwapped);
+ delete glw2;
+ QTRY_VERIFY(frameSwappedSpy.size() > 0);
+ }
+
+ image = glw1->grabFramebuffer();
+ QVERIFY(image.pixel(20, 10) == qRgb(0, 0, 255));
+
+ // make the GL widget top-level
+ {
+ QSignalSpy frameSwappedSpy(glw1, &QOpenGLWidget::frameSwapped);
+ glw1->setParent(nullptr);
+ glw1->show();
+ QVERIFY(QTest::qWaitForWindowExposed(glw1));
+ QTRY_VERIFY(frameSwappedSpy.size() > 0);
+ }
+
+ image = glw1->grabFramebuffer();
+ QVERIFY(image.pixel(20, 10) == qRgb(0, 0, 255));
+
+ // back to a child widget by readding to the tab widget
+ {
+ QSignalSpy frameSwappedSpy(glw1, &QOpenGLWidget::frameSwapped);
+ tabWidget.setCurrentIndex(tabWidget.addTab(glw1, "Re-added OpenGL widget 1"));
+ QTRY_VERIFY(frameSwappedSpy.size() > 0);
+ }
+
+ image = glw1->grabFramebuffer();
+ QVERIFY(image.pixel(20, 10) == qRgb(0, 0, 255));
+}
+
class CountingGraphicsView : public QGraphicsView
{
public:
@@ -346,6 +444,9 @@ void CountingGraphicsView::drawForeground(QPainter *, const QRectF &)
void tst_QOpenGLWidget::asViewport()
{
+#ifdef Q_OS_ANDROID
+ QSKIP("Crashes on Android, figure out why (QTBUG-102043)");
+#endif
// Have a QGraphicsView with a QOpenGLWidget as its viewport.
QGraphicsScene scene;
scene.addItem(new QGraphicsRectItem(10, 10, 100, 100));
@@ -367,6 +468,7 @@ void tst_QOpenGLWidget::asViewport()
// repainted when going from Inactive to Active. So wait for the window to be
// active before we continue, so the activation doesn't happen at a random
// time below. And call processEvents to have the paint events delivered right away.
+ widget.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&widget));
qApp->processEvents();
}
@@ -394,8 +496,9 @@ public:
void tst_QOpenGLWidget::requestUpdate()
{
- if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
- QSKIP("Wayland: This fails. Figure out why.");
+#ifdef Q_OS_ANDROID
+ QSKIP("Crashes on Android, figure out why (QTBUG-102043)");
+#endif
PaintCountWidget w;
w.resize(640, 480);
@@ -421,6 +524,9 @@ public:
void tst_QOpenGLWidget::fboRedirect()
{
+#ifdef Q_OS_ANDROID
+ QSKIP("Crashes on Android, figure out why (QTBUG-102043)");
+#endif
FboCheckWidget w;
w.resize(640, 480);
w.show();
@@ -436,6 +542,9 @@ void tst_QOpenGLWidget::fboRedirect()
void tst_QOpenGLWidget::showHide()
{
+#ifdef Q_OS_ANDROID
+ QSKIP("Crashes on Android, figure out why (QTBUG-102043)");
+#endif
QScopedPointer<ClearWidget> w(new ClearWidget(0, 800, 600));
w->resize(800, 600);
w->show();
@@ -460,41 +569,187 @@ void tst_QOpenGLWidget::showHide()
QVERIFY(image.pixel(30, 40) == qRgb(0, 0, 255));
}
+QtMessageHandler oldHandler = nullptr;
+
+void nativeWindowMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
+{
+ if (oldHandler)
+ oldHandler(type, context, msg);
+
+ if (type == QtWarningMsg
+ && (msg.contains("QOpenGLContext::makeCurrent() called with non-opengl surface")
+ || msg.contains("Failed to make context current")))
+ {
+ QFAIL("Unexpected warning got printed");
+ }
+}
+
void tst_QOpenGLWidget::nativeWindow()
{
- QScopedPointer<ClearWidget> w(new ClearWidget(0, 800, 600));
- w->resize(800, 600);
- w->show();
- w->winId();
- QVERIFY(QTest::qWaitForWindowExposed(w.data()));
+#ifdef Q_OS_ANDROID
+ QSKIP("Crashes on Android, figure out why (QTBUG-102043)");
+#endif
- QImage image = w->grabFramebuffer();
- QVERIFY(!image.isNull());
- QCOMPARE(image.width(), w->width());
- QCOMPARE(image.height(), w->height());
- QVERIFY(image.pixel(30, 40) == qRgb(255, 0, 0));
- QVERIFY(w->internalWinId());
-
- // Now as a native child.
- QWidget nativeParent;
- nativeParent.resize(800, 600);
- nativeParent.setAttribute(Qt::WA_NativeWindow);
- ClearWidget *child = new ClearWidget(0, 800, 600);
- child->setClearColor(0, 1, 0);
- child->setParent(&nativeParent);
- child->resize(400, 400);
- child->move(23, 34);
- nativeParent.show();
- QVERIFY(QTest::qWaitForWindowExposed(&nativeParent));
-
- QVERIFY(nativeParent.internalWinId());
- QVERIFY(!child->internalWinId());
-
- image = child->grabFramebuffer();
- QVERIFY(!image.isNull());
- QCOMPARE(image.width(), child->width());
- QCOMPARE(image.height(), child->height());
- QVERIFY(image.pixel(30, 40) == qRgb(0, 255, 0));
+ // NB these tests do not fully verify that native child widgets are fully
+ // functional since there is no guarantee that the content is composed and
+ // presented correctly as we can only do verification with
+ // grabFramebuffer() here which only exercises a part of the pipeline.
+
+ // Install a message handler that looks for some typical warnings from
+ // QRhi/QOpenGLConext that occur when the RHI-related logic in widgets goes wrong.
+ oldHandler = qInstallMessageHandler(nativeWindowMessageHandler);
+
+ {
+ QScopedPointer<ClearWidget> w(new ClearWidget(nullptr, 800, 600));
+ w->resize(800, 600);
+ w->show();
+ w->winId();
+ QVERIFY(QTest::qWaitForWindowExposed(w.data()));
+
+ QImage image = w->grabFramebuffer();
+ QVERIFY(!image.isNull());
+ QCOMPARE(image.width(), w->width());
+ QCOMPARE(image.height(), w->height());
+ QVERIFY(image.pixel(30, 40) == qRgb(255, 0, 0));
+ QVERIFY(w->internalWinId());
+ }
+
+ // QTBUG-113557: a plain _raster_ QWidget that is a _native_ child in a toplevel
+ // combined with a RHI-based (non-native) widget (QOpenGLWidget in this case)
+ // in the same toplevel.
+ {
+ QWidget topLevel;
+ topLevel.resize(800, 600);
+
+ ClearWidget *child = new ClearWidget(&topLevel, 800, 600);
+ child->setClearColor(1, 0, 0);
+ child->resize(400, 400);
+ child->move(23, 34);
+
+ QWidget *raster = new QWidget(&topLevel);
+ raster->setGeometry(23, 240, 120, 120);
+ raster->setStyleSheet("QWidget { background-color: yellow; }");
+
+ raster->winId();
+
+ topLevel.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
+
+ // Do not bother checking the output, i.e. if the yellow raster native child
+ // shows up as it should, but rather rely on the message handler catching the
+ // qWarnings if they occur.
+ }
+
+ // Now with the QOpenGLWidget being a native child
+ {
+ QWidget topLevel;
+ topLevel.resize(800, 600);
+
+ ClearWidget *child = new ClearWidget(nullptr, 800, 600);
+ child->setParent(&topLevel);
+
+ // make it a native child (native window, but not top-level -> no backingstore)
+ child->winId();
+
+ child->setClearColor(0, 1, 0);
+ child->resize(400, 400);
+ child->move(23, 34);
+
+ topLevel.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
+
+ QVERIFY(topLevel.internalWinId());
+ QVERIFY(child->internalWinId());
+
+ QImage image = child->grabFramebuffer();
+ QVERIFY(!image.isNull());
+ QCOMPARE(image.width(), child->width());
+ QCOMPARE(image.height(), child->height());
+ QVERIFY(image.pixel(30, 40) == qRgb(0, 255, 0));
+ }
+
+ // Now the same with WA_NativeWindow instead
+ {
+ QWidget topLevel;
+ topLevel.resize(800, 600);
+
+ ClearWidget *child = new ClearWidget(nullptr, 800, 600);
+ child->setParent(&topLevel);
+
+ // make it a native child (native window, but not top-level -> no backingstore)
+ child->setAttribute(Qt::WA_NativeWindow);
+
+ child->setClearColor(0, 1, 0);
+ child->resize(400, 400);
+ child->move(23, 34);
+
+ topLevel.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
+
+ QVERIFY(child->internalWinId());
+
+ QImage image = child->grabFramebuffer();
+ QCOMPARE(image.width(), child->width());
+ QCOMPARE(image.height(), child->height());
+ QVERIFY(image.pixel(30, 40) == qRgb(0, 255, 0));
+ }
+
+ // Now as a child of a native child
+ {
+ QWidget topLevel;
+ topLevel.resize(800, 600);
+
+ QWidget *container = new QWidget(&topLevel);
+ // make it a native child (native window, but not top-level -> no backingstore)
+ container->winId();
+
+ ClearWidget *child = new ClearWidget(nullptr, 800, 600);
+ // set the parent separately, this is important, see next test case
+ child->setParent(container);
+ child->setClearColor(0, 0, 1);
+ child->resize(400, 400);
+ child->move(23, 34);
+
+ topLevel.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
+
+ QVERIFY(topLevel.internalWinId());
+ QVERIFY(container->internalWinId());
+ QVERIFY(!child->internalWinId());
+
+ QImage image = child->grabFramebuffer();
+ QCOMPARE(image.width(), child->width());
+ QCOMPARE(image.height(), child->height());
+ QVERIFY(image.pixel(30, 40) == qRgb(0, 0, 255));
+ }
+
+ // Again as a child of a native child, but this time specifying the parent
+ // upon construction, not with an explicit setParent() call afterwards.
+ {
+ QWidget topLevel;
+ topLevel.resize(800, 600);
+ QWidget *container = new QWidget(&topLevel);
+ container->winId();
+ // parent it right away
+ ClearWidget *child = new ClearWidget(container, 800, 600);
+ child->setClearColor(0, 0, 1);
+ child->resize(400, 400);
+ child->move(23, 34);
+ topLevel.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
+ QVERIFY(topLevel.internalWinId());
+ QVERIFY(container->internalWinId());
+ QVERIFY(!child->internalWinId());
+ QImage image = child->grabFramebuffer();
+ QCOMPARE(image.width(), child->width());
+ QCOMPARE(image.height(), child->height());
+ QVERIFY(image.pixel(30, 40) == qRgb(0, 0, 255));
+ }
+
+ if (oldHandler) {
+ qInstallMessageHandler(oldHandler);
+ oldHandler = nullptr;
+ }
}
static inline QString msgRgbMismatch(unsigned actual, unsigned expected)
@@ -533,50 +788,59 @@ static QPixmap grabWidgetWithoutRepaint(const QWidget *widget, QRect clipArea)
bool verifyColor(const QWidget *widget, const QRect &clipArea, const QColor &color, int callerLine)
{
- for (int t = 0; t < 6; t++) {
- const QPixmap pixmap = grabWidgetWithoutRepaint(widget, clipArea);
- if (!QTest::qCompare(pixmap.size(),
- clipArea.size(),
- "pixmap.size()",
- "rect.size()",
- __FILE__,
- callerLine))
- return false;
-
-
- const QImage image = pixmap.toImage();
- QPixmap expectedPixmap(pixmap); /* ensure equal formats */
- expectedPixmap.detach();
- expectedPixmap.fill(color);
-
+ // Create a comparison target image
+ QPixmap expectedPixmap(grabWidgetWithoutRepaint(widget, clipArea)); /* ensure equal formats */
+ expectedPixmap.detach();
+ expectedPixmap.fill(color);
+ const QImage expectedImage = expectedPixmap.toImage();
+
+ // test image size
+ QPixmap pixmap;
+ auto testSize = [&](){
+ pixmap = grabWidgetWithoutRepaint(widget, clipArea);
+ return pixmap.size() == clipArea.size();
+ };
+
+ // test the first pixel's color
+ uint firstPixel;
+ auto testPixel = [&](){
+ const QImage image = grabWidgetWithoutRepaint(widget, clipArea).toImage();
uint alphaCorrection = image.format() == QImage::Format_RGB32 ? 0xff000000 : 0;
- uint firstPixel = image.pixel(0,0) | alphaCorrection;
-
- // Retry a couple of times. Some window managers have transparency animation, or are
- // just slow to render.
- if (t < 5) {
- if (firstPixel == QColor(color).rgb()
- && image == expectedPixmap.toImage())
- return true;
- else
- QTest::qWait(200);
- } else {
- if (!QTest::qVerify(firstPixel == QColor(color).rgb(),
- "firstPixel == QColor(color).rgb()",
- qPrintable(msgRgbMismatch(firstPixel, QColor(color).rgb())),
- __FILE__, callerLine)) {
- return false;
- }
- if (!QTest::qVerify(image == expectedPixmap.toImage(),
- "image == expectedPixmap.toImage()",
- "grabbed pixmap differs from expected pixmap",
- __FILE__, callerLine)) {
- return false;
- }
- }
+ firstPixel = image.pixel(0,0) | alphaCorrection;
+ return firstPixel == QColor(color).rgb();
+ };
+
+ // test the rendered image
+ QImage image;
+ auto testImage = [&](){
+ image = grabWidgetWithoutRepaint(widget, clipArea).toImage();
+ return image == expectedImage;
+ };
+
+ // Perform checks and make test case fail if unsuccessful
+ if (!QTest::qWaitFor(testSize))
+ return QTest::qCompare(pixmap.size(),
+ clipArea.size(),
+ "pixmap.size()",
+ "rect.size()",
+ __FILE__,
+ callerLine);
+
+ if (!QTest::qWaitFor(testPixel)) {
+ return QTest::qVerify(firstPixel == QColor(color).rgb(),
+ "firstPixel == QColor(color).rgb()",
+ qPrintable(msgRgbMismatch(firstPixel, QColor(color).rgb())),
+ __FILE__, callerLine);
}
- return false;
+ if (!QTest::qWaitFor(testImage)) {
+ return QTest::qVerify(image == expectedImage,
+ "image == expectedPixmap.toImage()",
+ "grabbed pixmap differs from expected pixmap",
+ __FILE__, callerLine);
+ }
+
+ return true;
}
void tst_QOpenGLWidget::stackWidgetOpaqueChildIsVisible()
@@ -585,8 +849,11 @@ void tst_QOpenGLWidget::stackWidgetOpaqueChildIsVisible()
QSKIP("QScreen::grabWindow() doesn't work properly on OSX HighDPI screen: QTBUG-46803");
return;
#endif
- if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
- QSKIP("Wayland: This fails. Figure out why.");
+#ifdef Q_OS_ANDROID
+ QSKIP("Crashes on Android, figure out why (QTBUG-102043)");
+#endif
+ if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation))
+ QSKIP("Platform does not support window activation");
if (QGuiApplication::platformName().startsWith(QLatin1String("offscreen"), Qt::CaseInsensitive))
QSKIP("Offscreen: This fails.");
@@ -606,11 +873,12 @@ void tst_QOpenGLWidget::stackWidgetOpaqueChildIsVisible()
stack.resize(dimensionSize, dimensionSize);
stack.show();
QVERIFY(QTest::qWaitForWindowExposed(&stack));
+ stack.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&stack));
// Switch to the QOpenGLWidget.
stack.setCurrentIndex(1);
- QTRY_COMPARE(clearWidget->m_paintCalled, true);
+ QTRY_VERIFY(clearWidget->m_paintCalled);
// Resize the tested region to be half size in the middle, because some OSes make the widget
// have rounded corners (e.g. OSX), and the grabbed window pixmap will not coincide perfectly
@@ -671,6 +939,9 @@ void tst_QOpenGLWidget::offscreen()
void tst_QOpenGLWidget::offscreenThenOnscreen()
{
+#ifdef Q_OS_ANDROID
+ QSKIP("Crashes on Android, figure out why (QTBUG-102043)");
+#endif
QScopedPointer<ClearWidget> w(new ClearWidget(0, 800, 600));
w->resize(800, 600);
@@ -694,6 +965,57 @@ void tst_QOpenGLWidget::offscreenThenOnscreen()
QVERIFY(image.pixel(30, 40) == qRgb(0, 0, 255));
}
+void tst_QOpenGLWidget::paintWhileHidden()
+{
+#ifdef Q_OS_ANDROID
+ QSKIP("Crashes on Android, figure out why (QTBUG-102043)");
+#endif
+ QScopedPointer<QWidget> tlw(new QWidget);
+ tlw->resize(640, 480);
+
+ ClearWidget *w = new ClearWidget(0, 640, 480);
+ w->setParent(tlw.data());
+ w->setClearColor(0, 0, 1);
+
+ tlw->show();
+ QVERIFY(QTest::qWaitForWindowExposed(tlw.data()));
+
+ // QTBUG-101620: Now make visible=false and call update and see if we get to
+ // paintEvent/paintGL eventually, to ensure the updating of the texture is
+ // not optimized permanently away even though there is no composition
+ // on-screen at the point when update() is called.
+
+ w->setVisible(false);
+ w->m_paintCalled = false;
+ w->update();
+ w->setVisible(true);
+ QTRY_VERIFY(w->m_paintCalled);
+}
+
+void tst_QOpenGLWidget::widgetWindowColorFormat_data()
+{
+ QTest::addColumn<bool>("translucent");
+ QTest::newRow("Translucent background disabled") << false;
+ QTest::newRow("Translucent background enabled") << true;
+}
+
+void tst_QOpenGLWidget::widgetWindowColorFormat()
+{
+ QFETCH(bool, translucent);
+
+ QOpenGLWidget w;
+ w.setAttribute(Qt::WA_TranslucentBackground, translucent);
+ w.setWindowTitle(QLatin1String(QTest::currentTestFunction()));
+ w.setFixedSize(16, 16);
+ w.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&w));
+
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ QCOMPARE(w.format().redBufferSize(), ctx->format().redBufferSize());
+ QCOMPARE(w.format().greenBufferSize(), ctx->format().greenBufferSize());
+ QCOMPARE(w.format().blueBufferSize(), ctx->format().blueBufferSize());
+}
+
class StaticTextPainterWidget : public QOpenGLWidget
{
public:
diff --git a/tests/auto/widgets/widgets/qplaintextedit/BLACKLIST b/tests/auto/widgets/widgets/qplaintextedit/BLACKLIST
deleted file mode 100644
index b71f2fcc0a..0000000000
--- a/tests/auto/widgets/widgets/qplaintextedit/BLACKLIST
+++ /dev/null
@@ -1,15 +0,0 @@
-# QTBUG-87423
-[copyAvailable]
-android
-[adjustScrollbars]
-android
-# QTBUG-89402
-[undoAvailableAfterPaste]
-android
-[copyAndSelectAllInReadonly]
-android
-[canPaste]
-android
-[updateCursorPositionAfterEdit]
-android
-
diff --git a/tests/auto/widgets/widgets/qplaintextedit/CMakeLists.txt b/tests/auto/widgets/widgets/qplaintextedit/CMakeLists.txt
index a339b158c2..b7528498cb 100644
--- a/tests/auto/widgets/widgets/qplaintextedit/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qplaintextedit/CMakeLists.txt
@@ -1,15 +1,22 @@
-# Generated from qplaintextedit.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qplaintextedit Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qplaintextedit LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qplaintextedit
SOURCES
tst_qplaintextedit.cpp
INCLUDE_DIRECTORIES
..
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::GuiPrivate
Qt::Widgets
@@ -20,6 +27,6 @@ qt_internal_add_test(tst_qplaintextedit
#####################################################################
qt_internal_extend_target(tst_qplaintextedit CONDITION MACOS
- PUBLIC_LIBRARIES
+ LIBRARIES
${FWAppKit}
)
diff --git a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp
index 297eb5ec51..ca7cc6d4b4 100644
--- a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp
+++ b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.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,6 +13,7 @@
#include <qclipboard.h>
#include <qtextbrowser.h>
#include <private/qwidgettextcontrol_p.h>
+#include <private/qplaintextedit_p.h>
#include <qscrollbar.h>
#include <qtextobject.h>
#include <qmenu.h>
@@ -143,7 +119,7 @@ private slots:
void layoutAfterMultiLineRemove();
void undoCommandRemovesAndReinsertsBlock();
void taskQTBUG_43562_lineCountCrash();
-#ifndef QT_NO_CONTEXTMENU
+#if !defined(QT_NO_CONTEXTMENU) && !defined(QT_NO_CLIPBOARD)
void contextMenu();
#endif
void inputMethodCursorRect();
@@ -154,6 +130,10 @@ private slots:
void updateCursorPositionAfterEdit();
#endif
void appendTextWhenInvisible();
+ void placeholderVisibility_data();
+ void placeholderVisibility();
+ void scrollBarSignals();
+ void dontCrashWithCss();
private:
void createSelection();
@@ -415,7 +395,7 @@ void tst_QPlainTextEdit::cursorPositionChanged()
spy.clear();
QTest::keyClick(ed, Qt::Key_A);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QTextCursor cursor = ed->textCursor();
cursor.movePosition(QTextCursor::Start);
@@ -423,23 +403,23 @@ void tst_QPlainTextEdit::cursorPositionChanged()
cursor.movePosition(QTextCursor::End);
spy.clear();
cursor.insertText("Test");
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
cursor.movePosition(QTextCursor::End);
ed->setTextCursor(cursor);
cursor.movePosition(QTextCursor::Start);
spy.clear();
cursor.insertText("Test");
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
QTest::keyClick(ed, Qt::Key_Left);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
CursorPositionChangedRecorder spy2(ed);
QVERIFY(ed->textCursor().position() > 0);
ed->setPlainText("Hello World");
- QCOMPARE(spy2.cursorPositions.count(), 1);
+ QCOMPARE(spy2.cursorPositions.size(), 1);
QCOMPARE(spy2.cursorPositions.at(0), 0);
QCOMPARE(ed->textCursor().position(), 0);
}
@@ -456,7 +436,7 @@ void tst_QPlainTextEdit::setTextCursor()
spy.clear();
ed->setTextCursor(cursor);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
}
#ifndef QT_NO_CLIPBOARD
@@ -473,7 +453,7 @@ void tst_QPlainTextEdit::undoAvailableAfterPaste()
const QString txt("Test");
QApplication::clipboard()->setText(txt);
ed->paste();
- QVERIFY(spy.count() >= 1);
+ QVERIFY(spy.size() >= 1);
QCOMPARE(ed->toPlainText(), txt);
}
#endif
@@ -727,16 +707,16 @@ void tst_QPlainTextEdit::noPropertiesOnDefaultTextEditCharFormat()
// on a text edit. Font properties instead should be taken from the
// widget's font (in sync with defaultFont property in document) and the
// foreground color should be taken from the palette.
- QCOMPARE(ed->textCursor().charFormat().properties().count(), 0);
+ QCOMPARE(ed->textCursor().charFormat().properties().size(), 0);
}
void tst_QPlainTextEdit::setPlainTextShouldEmitTextChangedOnce()
{
QSignalSpy spy(ed, SIGNAL(textChanged()));
ed->setPlainText("Yankee Doodle");
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
ed->setPlainText("");
- QCOMPARE(spy.count(), 2);
+ QCOMPARE(spy.size(), 2);
}
void tst_QPlainTextEdit::overwriteMode()
@@ -1016,7 +996,7 @@ void tst_QPlainTextEdit::copyAvailable_data()
//Tests the copyAvailable slot for several cases
void tst_QPlainTextEdit::copyAvailable()
{
- QFETCH(pairListType,keystrokes);
+ QFETCH(const pairListType, keystrokes);
QFETCH(QList<bool>, copyAvailable);
QFETCH(QString, function);
@@ -1029,9 +1009,8 @@ void tst_QPlainTextEdit::copyAvailable()
QSignalSpy spyCopyAvailabe(ed, SIGNAL(copyAvailable(bool)));
//Execute Keystrokes
- foreach(keyPairType keyPair, keystrokes) {
+ for (keyPairType keyPair : keystrokes)
QTest::keyClick(ed, keyPair.first, keyPair.second );
- }
//Execute ed->"function"
if (function == "cut")
@@ -1048,8 +1027,8 @@ void tst_QPlainTextEdit::copyAvailable()
//Compare spied signals
QEXPECT_FAIL("Case7 T,A,A, <- + shift, <- + shift, <- + shift, ctrl + x, undo() | signals: true, false, true",
"Wrong undo selection behaviour. Should be fixed in some future release. (See task: 132482)", Abort);
- QCOMPARE(spyCopyAvailabe.count(), copyAvailable.count());
- for (int i=0;i<spyCopyAvailabe.count(); i++) {
+ QCOMPARE(spyCopyAvailabe.size(), copyAvailable.size());
+ for (int i=0;i<spyCopyAvailabe.size(); i++) {
QVariant variantSpyCopyAvailable = spyCopyAvailabe.at(i).at(0);
QVERIFY2(variantSpyCopyAvailable.toBool() == copyAvailable.at(i), QString("Spied singnal: %1").arg(i).toLatin1());
}
@@ -1085,10 +1064,10 @@ void tst_QPlainTextEdit::moveCursor()
QCOMPARE(ed->textCursor().position(), 0);
ed->moveCursor(QTextCursor::NextCharacter);
QCOMPARE(ed->textCursor().position(), 1);
- QCOMPARE(cursorMovedSpy.count(), 1);
+ QCOMPARE(cursorMovedSpy.size(), 1);
ed->moveCursor(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
QCOMPARE(ed->textCursor().position(), 2);
- QCOMPARE(cursorMovedSpy.count(), 2);
+ QCOMPARE(cursorMovedSpy.size(), 2);
QCOMPARE(ed->textCursor().selectedText(), QString("e"));
}
@@ -1300,7 +1279,7 @@ void tst_QPlainTextEdit::ensureVisibleWithRtl()
ed->setLayoutDirection(Qt::RightToLeft);
ed->setLineWrapMode(QPlainTextEdit::NoWrap);
QString txt(500, QChar(QLatin1Char('a')));
- QCOMPARE(txt.length(), 500);
+ QCOMPARE(txt.size(), 500);
ed->setPlainText(txt);
ed->resize(100, 100);
ed->show();
@@ -1353,7 +1332,7 @@ void tst_QPlainTextEdit::extraSelections()
ed->setExtraSelections(QList<QTextEdit::ExtraSelection>() << sel);
QList<QTextEdit::ExtraSelection> selections = ed->extraSelections();
- QCOMPARE(selections.count(), 1);
+ QCOMPARE(selections.size(), 1);
QCOMPARE(selections.at(0).cursor.position(), endPos);
QCOMPARE(selections.at(0).cursor.anchor(), wordPos);
}
@@ -1368,7 +1347,9 @@ void tst_QPlainTextEdit::adjustScrollbars()
ed->setFont(ff);
ed->setMinimumSize(140, 100);
ed->setMaximumSize(140, 100);
- ed->show();
+ // We use showNormal() here, because otherwise on Android the widget will
+ // be shown fullscreen, and the scrollbar will not appear.
+ ed->showNormal();
QLatin1String txt("\nabc def ghi jkl mno pqr stu vwx");
ed->setPlainText(txt + txt + txt + txt);
@@ -1481,44 +1462,44 @@ void tst_QPlainTextEdit::selectionChanged()
QTest::keyClick(ed, Qt::Key_Right);
QCOMPARE(ed->textCursor().position(), 1);
- QCOMPARE(selectionChangedSpy.count(), 0);
+ QCOMPARE(selectionChangedSpy.size(), 0);
QTest::keyClick(ed, Qt::Key_Right, Qt::ShiftModifier);
QCOMPARE(ed->textCursor().position(), 2);
- QCOMPARE(selectionChangedSpy.count(), 1);
+ QCOMPARE(selectionChangedSpy.size(), 1);
QTest::keyClick(ed, Qt::Key_Right, Qt::ShiftModifier);
QCOMPARE(ed->textCursor().position(), 3);
- QCOMPARE(selectionChangedSpy.count(), 2);
+ QCOMPARE(selectionChangedSpy.size(), 2);
QTest::keyClick(ed, Qt::Key_Right, Qt::ShiftModifier);
QCOMPARE(ed->textCursor().position(), 4);
- QCOMPARE(selectionChangedSpy.count(), 3);
+ QCOMPARE(selectionChangedSpy.size(), 3);
QTest::keyClick(ed, Qt::Key_Right);
QCOMPARE(ed->textCursor().position(), 4);
- QCOMPARE(selectionChangedSpy.count(), 4);
+ QCOMPARE(selectionChangedSpy.size(), 4);
QTest::keyClick(ed, Qt::Key_Right);
QCOMPARE(ed->textCursor().position(), 5);
- QCOMPARE(selectionChangedSpy.count(), 4);
+ QCOMPARE(selectionChangedSpy.size(), 4);
}
void tst_QPlainTextEdit::blockCountChanged()
{
QSignalSpy blockCountCpangedSpy(ed, SIGNAL(blockCountChanged(int)));
ed->setPlainText("Hello");
- QCOMPARE(blockCountCpangedSpy.count(), 0);
+ QCOMPARE(blockCountCpangedSpy.size(), 0);
ed->setPlainText("Hello World");
- QCOMPARE(blockCountCpangedSpy.count(), 0);
+ QCOMPARE(blockCountCpangedSpy.size(), 0);
ed->setPlainText("Hello \n World \n this \n has \n more \n blocks \n than \n just \n one");
- QCOMPARE(blockCountCpangedSpy.count(), 1);
+ QCOMPARE(blockCountCpangedSpy.size(), 1);
ed->setPlainText("One");
- QCOMPARE(blockCountCpangedSpy.count(), 2);
+ QCOMPARE(blockCountCpangedSpy.size(), 2);
ed->setPlainText("One \n Two");
- QCOMPARE(blockCountCpangedSpy.count(), 3);
+ QCOMPARE(blockCountCpangedSpy.size(), 3);
ed->setPlainText("Three \n Four");
- QCOMPARE(blockCountCpangedSpy.count(), 3);
+ QCOMPARE(blockCountCpangedSpy.size(), 3);
}
@@ -1696,7 +1677,7 @@ void tst_QPlainTextEdit::taskQTBUG_43562_lineCountCrash()
disconnect(ed->document(), SIGNAL(contentsChange(int, int, int)), 0, 0);
}
-#ifndef QT_NO_CONTEXTMENU
+#if !defined(QT_NO_CONTEXTMENU) && !defined(QT_NO_CLIPBOARD)
void tst_QPlainTextEdit::contextMenu()
{
ed->appendHtml(QStringLiteral("Hello <a href='http://www.qt.io'>Qt</a>"));
@@ -1719,7 +1700,7 @@ void tst_QPlainTextEdit::contextMenu()
QVERIFY(!ed->findChild<QAction *>(QStringLiteral("link-copy")));
QTextCursor cursor = ed->textCursor();
- cursor.setPosition(ed->toPlainText().length() - 2);
+ cursor.setPosition(ed->toPlainText().size() - 2);
ed->setTextCursor(cursor);
menu = ed->createStandardContextMenu(ed->cursorRect().center());
@@ -1730,7 +1711,7 @@ void tst_QPlainTextEdit::contextMenu()
delete menu;
QVERIFY(!ed->findChild<QAction *>(QStringLiteral("link-copy")));
}
-#endif // QT_NO_CONTEXTMENU
+#endif // QT_NO_CONTEXTMENU && QT_NO_CLIPBOARD
// QTBUG-51923: Verify that the cursor rectangle returned by the input
// method query correctly reflects the viewport offset.
@@ -1802,7 +1783,7 @@ void tst_QPlainTextEdit::updateCursorPositionAfterEdit()
QTest::keyClick(&plaintextEdit, Qt::Key_Up);
// The curser should move back to the end of the copied text
- QCOMPARE(plaintextEdit.textCursor().position(), initialPosition + txt.length());
+ QCOMPARE(plaintextEdit.textCursor().position(), initialPosition + txt.size());
}
#endif
@@ -1837,5 +1818,141 @@ void tst_QPlainTextEdit::appendTextWhenInvisible()
QCOMPARE(maxAfterAppend, maxAfterSet);
}
+enum SetupCommand {
+ ClearPlaceHolder, // set empty placeholder text
+ SetPlaceHolder, // set a non-empty placeholder text
+ ClearContent, // set empty text as content
+ SetContent // set non-empty text as content
+};
+
+void tst_QPlainTextEdit::placeholderVisibility_data()
+{
+ QTest::addColumn<QList<SetupCommand>>("setupCommands");
+ QTest::addColumn<bool>("placeholderVisible");
+ QTest::addRow("no placeholder set + no text set")
+ << QList<SetupCommand>{} << false;
+ QTest::addRow("no placeholder set + text set or text set + no placeholder set")
+ << QList<SetupCommand>{ SetContent } << false;
+ QTest::addRow("no placeholder set + text set + empty text set")
+ << QList<SetupCommand>{ SetContent , ClearContent }
+ << false;
+ QTest::addRow("no placeholder set + empty text set + text set")
+ << QList<SetupCommand>{ ClearContent, SetContent }
+ << false;
+ QTest::addRow("empty placeholder set + no text set")
+ << QList<SetupCommand>{ ClearPlaceHolder } << false;
+ QTest::addRow("empty placeholder set + text set")
+ << QList<SetupCommand>{ ClearPlaceHolder, SetContent }
+ << false;
+ QTest::addRow("empty placeholder set + text set + empty text set")
+ << QList<SetupCommand>{ ClearPlaceHolder, SetContent, ClearContent }
+ << false;
+ QTest::addRow("empty placeholder set + empty text set + text set")
+ << QList<SetupCommand>{ ClearPlaceHolder, ClearContent, SetContent }
+ << false;
+ QTest::addRow("placeholder set + no text set")
+ << QList<SetupCommand>{ SetPlaceHolder, ClearContent }
+ << true;
+ QTest::addRow("placeholder set + text set")
+ << QList<SetupCommand>{ SetPlaceHolder, SetContent }
+ << false;
+ QTest::addRow("placeholder set + text set + empty text set")
+ << QList<SetupCommand>{ SetPlaceHolder, SetContent, ClearContent }
+ << true;
+ QTest::addRow("placeholder set + empty text set + text set")
+ << QList<SetupCommand>{ SetPlaceHolder, ClearContent, SetContent }
+ << false;
+ QTest::addRow("placeholder set + text set + empty placeholder set")
+ << QList<SetupCommand>{ SetPlaceHolder, SetContent, ClearPlaceHolder}
+ << false;
+ QTest::addRow("placeholder set + empty placeholder set + text set")
+ << QList<SetupCommand>{ SetPlaceHolder, ClearPlaceHolder, SetContent }
+ << false;
+ QTest::addRow("placeholder set + empty placeholder set + empty text set")
+ << QList<SetupCommand>{ SetPlaceHolder, ClearPlaceHolder, ClearContent }
+ << false;
+ QTest::addRow("placeholder set + empty text set + empty placeholder set")
+ << QList<SetupCommand>{ SetPlaceHolder, ClearContent, ClearPlaceHolder }
+ << false;
+ QTest::addRow("text set + no placeholder set + empty text set")
+ << QList<SetupCommand>{ SetContent, ClearContent }
+ << false;
+ QTest::addRow("text set + empty placeholder set")
+ << QList<SetupCommand>{ SetContent, ClearPlaceHolder }
+ << false;
+ QTest::addRow("text set + placeholder set")
+ << QList<SetupCommand>{ SetContent, SetPlaceHolder }
+ << false;
+ QTest::addRow("text set + placeholder set + empty text set")
+ << QList<SetupCommand>{ SetContent, SetPlaceHolder, ClearContent }
+ << true;
+ QTest::addRow("text set + placeholder set + empty placeholder set")
+ << QList<SetupCommand>{ SetContent, SetPlaceHolder, ClearPlaceHolder }
+ << false;
+}
+
+void tst_QPlainTextEdit::placeholderVisibility()
+{
+ QFETCH(QList<SetupCommand>, setupCommands);
+ QFETCH(bool, placeholderVisible);
+
+ QPlainTextEdit plainTextEdit;
+ for (auto command : setupCommands) {
+ switch (command) {
+ case ClearPlaceHolder:
+ plainTextEdit.setPlaceholderText("");
+ break;
+ case SetPlaceHolder:
+ plainTextEdit.setPlaceholderText("Qt is awesome !");
+ break;
+ case ClearContent:
+ plainTextEdit.setPlainText("");
+ break;
+ case SetContent:
+ plainTextEdit.setPlainText("PlainText...");
+ break;
+ }
+ }
+ auto *plainTextEdit_d = static_cast<QPlainTextEditPrivate *>(qt_widget_private(&plainTextEdit));
+
+ plainTextEdit.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&plainTextEdit));
+ QTRY_COMPARE(plainTextEdit_d->placeholderTextShown, placeholderVisible);
+}
+
+
+void tst_QPlainTextEdit::scrollBarSignals()
+{
+ QPlainTextEdit plainTextEdit;
+ QString longText;
+ for (uint i = 0; i < 500; ++i)
+ longText += "This is going to be a very long text for scroll signal testing.\n";
+ plainTextEdit.setPlainText(longText);
+ QScrollBar *vbar = plainTextEdit.verticalScrollBar();
+ plainTextEdit.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&plainTextEdit));
+ QSignalSpy spy(vbar, &QScrollBar::valueChanged);
+
+ QTest::keyClick(vbar, Qt::Key_Down);
+ QTRY_COMPARE(spy.count(), 1);
+ QTest::keyClick(vbar, Qt::Key_PageDown);
+ QTRY_COMPARE(spy.count(), 2);
+ QTest::keyClick(vbar, Qt::Key_PageDown);
+ QTRY_COMPARE(spy.count(), 3);
+ QTest::keyClick(vbar, Qt::Key_Up);
+ QTRY_COMPARE(spy.count(), 4);
+ QTest::keyClick(vbar, Qt::Key_PageUp);
+ QTRY_COMPARE(spy.count(), 5);
+}
+
+void tst_QPlainTextEdit::dontCrashWithCss()
+{
+ qApp->setStyleSheet("QWidget { font: 10pt; }");
+ QPlainTextEdit edit;
+ edit.show();
+ qApp->setStyleSheet(QString());
+}
+
+
QTEST_MAIN(tst_QPlainTextEdit)
#include "tst_qplaintextedit.moc"
diff --git a/tests/auto/widgets/widgets/qprogressbar/CMakeLists.txt b/tests/auto/widgets/widgets/qprogressbar/CMakeLists.txt
index 699ba0a2f1..61ce6c2692 100644
--- a/tests/auto/widgets/widgets/qprogressbar/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qprogressbar/CMakeLists.txt
@@ -1,13 +1,21 @@
-# Generated from qprogressbar.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qprogressbar Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qprogressbar LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qprogressbar
SOURCES
tst_qprogressbar.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
+ Qt::WidgetsPrivate
)
diff --git a/tests/auto/widgets/widgets/qprogressbar/tst_qprogressbar.cpp b/tests/auto/widgets/widgets/qprogressbar/tst_qprogressbar.cpp
index 5c08ac4e3e..4a90ed6667 100644
--- a/tests/auto/widgets/widgets/qprogressbar/tst_qprogressbar.cpp
+++ b/tests/auto/widgets/widgets/qprogressbar/tst_qprogressbar.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>
@@ -36,6 +11,8 @@
#include <qtimer.h>
#include <QStyleFactory>
+#include <QtWidgets/private/qapplication_p.h>
+
class tst_QProgressBar : public QObject
{
Q_OBJECT
@@ -248,7 +225,7 @@ void tst_QProgressBar::setMinMaxRepaint()
pbar.setFormat("%v");
pbar.move(300, 300);
pbar.show();
- qApp->setActiveWindow(&pbar);
+ QApplicationPrivate::setActiveWindow(&pbar);
QVERIFY(QTest::qWaitForWindowActive(&pbar));
// No repaint when setting minimum to the current minimum
diff --git a/tests/auto/widgets/widgets/qpushbutton/CMakeLists.txt b/tests/auto/widgets/widgets/qpushbutton/CMakeLists.txt
index 0ec5c1fe09..afd052fa17 100644
--- a/tests/auto/widgets/widgets/qpushbutton/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qpushbutton/CMakeLists.txt
@@ -1,13 +1,22 @@
-# Generated from qpushbutton.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qpushbutton Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qpushbutton LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qpushbutton
SOURCES
tst_qpushbutton.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
+ Qt::GuiPrivate
Qt::Widgets
+ Qt::WidgetsPrivate
)
diff --git a/tests/auto/widgets/widgets/qpushbutton/testdata/setEnabled/disabled_Windows_win32_data0.qsnap b/tests/auto/widgets/widgets/qpushbutton/testdata/setEnabled/disabled_Windows_win32_data0.qsnap
deleted file mode 100644
index 8c2c08aee9..0000000000
--- a/tests/auto/widgets/widgets/qpushbutton/testdata/setEnabled/disabled_Windows_win32_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qpushbutton/testdata/setEnabled/enabled_Motif_data0.qsnap b/tests/auto/widgets/widgets/qpushbutton/testdata/setEnabled/enabled_Motif_data0.qsnap
deleted file mode 100644
index 3c455887da..0000000000
--- a/tests/auto/widgets/widgets/qpushbutton/testdata/setEnabled/enabled_Motif_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qpushbutton/testdata/setEnabled/enabled_Windows_data0.qsnap b/tests/auto/widgets/widgets/qpushbutton/testdata/setEnabled/enabled_Windows_data0.qsnap
deleted file mode 100644
index e655b09d29..0000000000
--- a/tests/auto/widgets/widgets/qpushbutton/testdata/setEnabled/enabled_Windows_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qpushbutton/testdata/setEnabled/enabled_Windows_win32_data0.qsnap b/tests/auto/widgets/widgets/qpushbutton/testdata/setEnabled/enabled_Windows_win32_data0.qsnap
deleted file mode 100644
index 8f59499d72..0000000000
--- a/tests/auto/widgets/widgets/qpushbutton/testdata/setEnabled/enabled_Windows_win32_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qpushbutton/testdata/setPixmap/Vpix_Motif_data0.qsnap b/tests/auto/widgets/widgets/qpushbutton/testdata/setPixmap/Vpix_Motif_data0.qsnap
deleted file mode 100644
index a6967a17f7..0000000000
--- a/tests/auto/widgets/widgets/qpushbutton/testdata/setPixmap/Vpix_Motif_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qpushbutton/testdata/setPixmap/Vpix_Windows_data0.qsnap b/tests/auto/widgets/widgets/qpushbutton/testdata/setPixmap/Vpix_Windows_data0.qsnap
deleted file mode 100644
index d7c721c960..0000000000
--- a/tests/auto/widgets/widgets/qpushbutton/testdata/setPixmap/Vpix_Windows_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qpushbutton/testdata/setPixmap/Vpix_Windows_win32_data0.qsnap b/tests/auto/widgets/widgets/qpushbutton/testdata/setPixmap/Vpix_Windows_win32_data0.qsnap
deleted file mode 100644
index ae0261a22c..0000000000
--- a/tests/auto/widgets/widgets/qpushbutton/testdata/setPixmap/Vpix_Windows_win32_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qpushbutton/testdata/setText/simple_Motif_data0.qsnap b/tests/auto/widgets/widgets/qpushbutton/testdata/setText/simple_Motif_data0.qsnap
deleted file mode 100644
index 039bdce748..0000000000
--- a/tests/auto/widgets/widgets/qpushbutton/testdata/setText/simple_Motif_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qpushbutton/testdata/setText/simple_Windows_data0.qsnap b/tests/auto/widgets/widgets/qpushbutton/testdata/setText/simple_Windows_data0.qsnap
deleted file mode 100644
index db40dc4726..0000000000
--- a/tests/auto/widgets/widgets/qpushbutton/testdata/setText/simple_Windows_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qpushbutton/testdata/setText/simple_Windows_win32_data0.qsnap b/tests/auto/widgets/widgets/qpushbutton/testdata/setText/simple_Windows_win32_data0.qsnap
deleted file mode 100644
index c0e1279f46..0000000000
--- a/tests/auto/widgets/widgets/qpushbutton/testdata/setText/simple_Windows_win32_data0.qsnap
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp b/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
index e19264abb2..92ce1f5419 100644
--- a/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
+++ b/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.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>
@@ -40,6 +15,12 @@
#include <QGridLayout>
#include <QStyleFactory>
#include <QTabWidget>
+#include <QStyleOption>
+
+#include <private/qguiapplication_p.h>
+#include <qpa/qplatformtheme.h>
+
+#include <QtWidgets/private/qapplication_p.h>
class tst_QPushButton : public QObject
{
@@ -60,7 +41,6 @@ private slots:
void setDown();
void popupCrash();
void isChecked();
- void animateClick();
void toggle();
void clicked();
void touchTap();
@@ -74,20 +54,21 @@ private slots:
void emitReleasedAfterChange();
void hitButton();
void iconOnlyStyleSheet();
+ void mousePressAndMove();
+ void reactToMenuClosed();
protected slots:
void resetCounters();
void onClicked();
- void onToggled( bool on );
+ void onToggled(bool on);
void onPressed();
void onReleased();
- void helperSlotDelete();
private:
- uint click_count;
- uint toggle_count;
- uint press_count;
- uint release_count;
+ int click_count;
+ int toggle_count;
+ int press_count;
+ int release_count;
QPushButton *testWidget;
QPointingDevice *m_touchScreen = QTest::createTouchDevice();
@@ -102,40 +83,40 @@ void tst_QPushButton::getSetCheck()
QMenu *var1 = new QMenu;
obj1.setMenu(var1);
QCOMPARE(var1, obj1.menu());
- obj1.setMenu((QMenu *)0);
- QCOMPARE((QMenu *)0, obj1.menu());
+ obj1.setMenu(nullptr);
+ QCOMPARE(obj1.menu(), nullptr);
delete var1;
}
void tst_QPushButton::initTestCase()
{
// Create the test class
- testWidget = new QPushButton( "&Start", 0 );
+ testWidget = new QPushButton("&Start", 0);
testWidget->setObjectName("testWidget");
- testWidget->resize( 200, 200 );
+ testWidget->resize(200, 200);
testWidget->show();
- connect( testWidget, SIGNAL(clicked()), this, SLOT(onClicked()) );
- connect( testWidget, SIGNAL(pressed()), this, SLOT(onPressed()) );
- connect( testWidget, SIGNAL(released()), this, SLOT(onReleased()) );
- connect( testWidget, SIGNAL(toggled(bool)), this, SLOT(onToggled(bool)) );
+ connect(testWidget, SIGNAL(clicked()), this, SLOT(onClicked()));
+ connect(testWidget, SIGNAL(pressed()), this, SLOT(onPressed()));
+ connect(testWidget, SIGNAL(released()), this, SLOT(onReleased()));
+ connect(testWidget, SIGNAL(toggled(bool)), this, SLOT(onToggled(bool)));
}
void tst_QPushButton::cleanupTestCase()
{
delete testWidget;
- testWidget = 0;
+ testWidget = nullptr;
}
void tst_QPushButton::init()
{
- testWidget->setAutoRepeat( false );
- testWidget->setDown( false );
+ testWidget->setAutoRepeat(false);
+ testWidget->setDown(false);
testWidget->setText("Test");
- testWidget->setEnabled( true );
+ testWidget->setEnabled(true);
#if QT_CONFIG(shortcut)
QKeySequence seq;
- testWidget->setShortcut( seq );
+ testWidget->setShortcut(seq);
#endif
resetCounters();
@@ -154,7 +135,7 @@ void tst_QPushButton::onClicked()
click_count++;
}
-void tst_QPushButton::onToggled( bool /*on*/ )
+void tst_QPushButton::onToggled(bool /*on*/)
{
toggle_count++;
}
@@ -172,46 +153,46 @@ void tst_QPushButton::onReleased()
void tst_QPushButton::autoRepeat()
{
// If this changes, this test must be completely revised.
- QVERIFY( !testWidget->isCheckable() );
+ QVERIFY(!testWidget->isCheckable());
// verify autorepeat is off by default.
- QPushButton tmp( 0 );
+ QPushButton tmp;
tmp.setObjectName("tmp");
- QVERIFY( !tmp.autoRepeat() );
+ QVERIFY(!tmp.autoRepeat());
// check if we can toggle the mode
- testWidget->setAutoRepeat( true );
- QVERIFY( testWidget->autoRepeat() );
+ testWidget->setAutoRepeat(true);
+ QVERIFY(testWidget->autoRepeat());
- testWidget->setAutoRepeat( false );
- QVERIFY( !testWidget->autoRepeat() );
+ testWidget->setAutoRepeat(false);
+ QVERIFY(!testWidget->autoRepeat());
resetCounters();
// check that the button is down if we press space and not in autorepeat
- testWidget->setDown( false );
- testWidget->setAutoRepeat( false );
- QTest::keyPress( testWidget, Qt::Key_Space );
+ testWidget->setDown(false);
+ testWidget->setAutoRepeat(false);
+ QTest::keyPress(testWidget, Qt::Key_Space);
- QTRY_VERIFY( testWidget->isDown() );
- QVERIFY( toggle_count == 0 );
- QVERIFY( press_count == 1 );
- QVERIFY( release_count == 0 );
- QVERIFY( click_count == 0 );
+ QTRY_VERIFY(testWidget->isDown());
+ QCOMPARE(toggle_count, 0);
+ QCOMPARE(press_count, 1);
+ QCOMPARE(release_count, 0);
+ QCOMPARE(click_count, 0);
- QTest::keyRelease( testWidget, Qt::Key_Space );
+ QTest::keyRelease(testWidget, Qt::Key_Space);
resetCounters();
// check that the button is down if we press space while in autorepeat
// we can't actually confirm how many times it is fired, more than 1 is enough.
- testWidget->setDown( false );
- testWidget->setAutoRepeat( true );
- QTest::keyPress( testWidget, Qt::Key_Space );
+ testWidget->setDown(false);
+ testWidget->setAutoRepeat(true);
+ QTest::keyPress(testWidget, Qt::Key_Space);
QTRY_VERIFY(press_count > 3);
- QVERIFY( testWidget->isDown() );
- QVERIFY( toggle_count == 0 );
- QTest::keyRelease( testWidget, Qt::Key_Space );
+ QVERIFY(testWidget->isDown());
+ QCOMPARE(toggle_count, 0);
+ QTest::keyRelease(testWidget, Qt::Key_Space);
QCOMPARE(press_count, release_count);
QCOMPARE(release_count, click_count);
@@ -219,113 +200,128 @@ void tst_QPushButton::autoRepeat()
// check that pressing ENTER has no effect
resetCounters();
- testWidget->setDown( false );
- testWidget->setAutoRepeat( false );
- QTest::keyPress( testWidget, Qt::Key_Enter );
+ testWidget->setDown(false);
+ // Skip after reset if ButtonPressKeys has Key_Enter
+ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
+ ->themeHint(QPlatformTheme::ButtonPressKeys)
+ .value<QList<Qt::Key>>();
+ if (buttonPressKeys.contains(Qt::Key_Enter)) {
+ return;
+ }
+ testWidget->setAutoRepeat(false);
+ QTest::keyPress(testWidget, Qt::Key_Enter);
- QTest::qWait( 300 );
+ QTest::qWait(300);
- QVERIFY( !testWidget->isDown() );
- QVERIFY( toggle_count == 0 );
- QVERIFY( press_count == 0 );
- QVERIFY( release_count == 0 );
- QVERIFY( click_count == 0 );
- QTest::keyRelease( testWidget, Qt::Key_Enter );
+ QVERIFY(!testWidget->isDown());
+ QCOMPARE(toggle_count, 0);
+ QCOMPARE(press_count, 0);
+ QCOMPARE(release_count, 0);
+ QCOMPARE(click_count, 0);
+ QTest::keyRelease(testWidget, Qt::Key_Enter);
// check that pressing ENTER has no effect
resetCounters();
- testWidget->setDown( false );
- testWidget->setAutoRepeat( true );
- QTest::keyClick( testWidget, Qt::Key_Enter );
- QTest::qWait( 300 );
- QVERIFY( !testWidget->isDown() );
- QVERIFY( toggle_count == 0 );
- QVERIFY( press_count == 0 );
- QVERIFY( release_count == 0 );
- QVERIFY( click_count == 0 );
+ testWidget->setDown(false);
+ testWidget->setAutoRepeat(true);
+ QTest::keyClick(testWidget, Qt::Key_Enter);
+ QTest::qWait(300);
+ QVERIFY(!testWidget->isDown());
+ QCOMPARE(toggle_count, 0);
+ QCOMPARE(press_count, 0);
+ QCOMPARE(release_count, 0);
+ QCOMPARE(click_count, 0);
}
void tst_QPushButton::pressed()
{
- QTest::keyPress( testWidget, ' ' );
- QCOMPARE( press_count, (uint)1 );
- QCOMPARE( release_count, (uint)0 );
-
- QTest::keyRelease( testWidget, ' ' );
- QCOMPARE( press_count, (uint)1 );
- QCOMPARE( release_count, (uint)1 );
+ QTest::keyPress(testWidget, ' ');
+ QCOMPARE(press_count, 1);
+ QCOMPARE(release_count, 0);
+
+ QTest::keyRelease(testWidget, ' ');
+ QCOMPARE(press_count, 1);
+ QCOMPARE(release_count, 1);
+
+ // Skip if ButtonPressKeys has Key_Enter
+ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
+ ->themeHint(QPlatformTheme::ButtonPressKeys)
+ .value<QList<Qt::Key>>();
+ if (buttonPressKeys.contains(Qt::Key_Enter)) {
+ return;
+ }
- QTest::keyPress( testWidget,Qt::Key_Enter );
- QCOMPARE( press_count, (uint)1 );
- QCOMPARE( release_count, (uint)1 );
+ QTest::keyPress(testWidget,Qt::Key_Enter);
+ QCOMPARE(press_count, 1);
+ QCOMPARE(release_count, 1);
testWidget->setAutoDefault(true);
- QTest::keyPress( testWidget,Qt::Key_Enter );
- QCOMPARE( press_count, (uint)2 );
- QCOMPARE( release_count, (uint)2 );
+ QTest::keyPress(testWidget,Qt::Key_Enter);
+ QCOMPARE(press_count, 2);
+ QCOMPARE(release_count, 2);
testWidget->setAutoDefault(false);
}
void tst_QPushButton::isCheckable()
{
- QVERIFY( !testWidget->isCheckable() );
+ QVERIFY(!testWidget->isCheckable());
}
void tst_QPushButton::setDown()
{
- testWidget->setDown( false );
- QVERIFY( !testWidget->isDown() );
+ testWidget->setDown(false);
+ QVERIFY(!testWidget->isDown());
- testWidget->setDown( true );
- QVERIFY( testWidget->isDown() );
+ testWidget->setDown(true);
+ QVERIFY(testWidget->isDown());
- testWidget->setDown( true );
- QTest::keyClick( testWidget, Qt::Key_Escape );
- QVERIFY( !testWidget->isDown() );
+ testWidget->setDown(true);
+ QTest::keyClick(testWidget, Qt::Key_Escape);
+ QVERIFY(!testWidget->isDown());
}
void tst_QPushButton::isChecked()
{
- testWidget->setDown( false );
- QVERIFY( !testWidget->isChecked() );
+ testWidget->setDown(false);
+ QVERIFY(!testWidget->isChecked());
- testWidget->setDown( true );
- QVERIFY( !testWidget->isChecked() );
+ testWidget->setDown(true);
+ QVERIFY(!testWidget->isChecked());
- testWidget->setDown( false );
+ testWidget->setDown(false);
testWidget->toggle();
- QVERIFY( testWidget->isChecked() == testWidget->isCheckable() );
+ QCOMPARE(testWidget->isChecked(), testWidget->isCheckable());
}
void tst_QPushButton::toggle()
{
// the pushbutton shouldn't toggle the button.
testWidget->toggle();
- QVERIFY( testWidget->isChecked() == false );
+ QCOMPARE(testWidget->isChecked(), false);
}
void tst_QPushButton::toggled()
{
// the pushbutton shouldn't send a toggled signal when we call the toggle slot.
- QVERIFY( !testWidget->isCheckable() );
+ QVERIFY(!testWidget->isCheckable());
testWidget->toggle();
- QVERIFY( toggle_count == 0 );
+ QCOMPARE(toggle_count, 0);
// do it again, just to be sure
resetCounters();
testWidget->toggle();
- QVERIFY( toggle_count == 0 );
+ QCOMPARE(toggle_count, 0);
// finally check that we can toggle using the mouse
resetCounters();
- QTest::mousePress( testWidget, Qt::LeftButton );
- QVERIFY( toggle_count == 0 );
- QVERIFY( click_count == 0 );
+ QTest::mousePress(testWidget, Qt::LeftButton);
+ QCOMPARE(toggle_count, 0);
+ QCOMPARE(click_count, 0);
- QTest::mouseRelease( testWidget, Qt::LeftButton );
- QVERIFY( click_count == 1 );
+ QTest::mouseRelease(testWidget, Qt::LeftButton);
+ QCOMPARE(click_count, 1);
}
#if QT_CONFIG(shortcut)
@@ -338,70 +334,56 @@ void tst_QPushButton::toggled()
void tst_QPushButton::setAccel()
{
testWidget->setText("&AccelTest");
- QKeySequence seq( Qt::ALT | Qt::Key_A );
- testWidget->setShortcut( seq );
+ QKeySequence seq(Qt::ALT | Qt::Key_A);
+ testWidget->setShortcut(seq);
// The shortcut will not be activated unless the button is in a active
// window and has focus
- QApplication::setActiveWindow(testWidget);
+ QApplicationPrivate::setActiveWindow(testWidget);
testWidget->setFocus();
QVERIFY(QTest::qWaitForWindowActive(testWidget));
- QTest::keyClick( testWidget, 'A', Qt::AltModifier );
- QTRY_VERIFY( click_count == 1 );
- QVERIFY( press_count == 1 );
- QVERIFY( release_count == 1 );
- QVERIFY( toggle_count == 0 );
+ QTest::keyClick(testWidget, 'A', Qt::AltModifier);
+ QTRY_VERIFY(click_count == 1);
+ QCOMPARE(press_count, 1);
+ QCOMPARE(release_count, 1);
+ QCOMPARE(toggle_count, 0);
// wait 200 ms because setAccel uses animateClick.
// if we don't wait this may screw up a next test.
QTest::qWait(200);
- QTRY_VERIFY( !testWidget->isDown() );
+ QTRY_VERIFY(!testWidget->isDown());
}
#endif // QT_CONFIG(shortcut)
-void tst_QPushButton::animateClick()
-{
- QVERIFY( !testWidget->isDown() );
- testWidget->animateClick();
- QVERIFY( testWidget->isDown() );
- QTest::qWait( 200 );
- QVERIFY( !testWidget->isDown() );
-
- QVERIFY( click_count == 1 );
- QVERIFY( press_count == 1 );
- QVERIFY( release_count == 1 );
- QVERIFY( toggle_count == 0 );
-}
-
void tst_QPushButton::clicked()
{
- QTest::mousePress( testWidget, Qt::LeftButton );
- QVERIFY( press_count == 1 );
- QVERIFY( release_count == 0 );
+ QTest::mousePress(testWidget, Qt::LeftButton);
+ QCOMPARE(press_count, 1);
+ QCOMPARE(release_count, 0);
- QTest::mouseRelease( testWidget, Qt::LeftButton );
- QCOMPARE( press_count, (uint)1 );
- QCOMPARE( release_count, (uint)1 );
+ QTest::mouseRelease(testWidget, Qt::LeftButton);
+ QCOMPARE(press_count, 1);
+ QCOMPARE(release_count, 1);
press_count = 0;
release_count = 0;
testWidget->setDown(false);
for (uint i=0; i<10; i++)
- QTest::mouseClick( testWidget, Qt::LeftButton );
- QCOMPARE( press_count, (uint)10 );
- QCOMPARE( release_count, (uint)10 );
+ QTest::mouseClick(testWidget, Qt::LeftButton);
+ QCOMPARE(press_count, 10);
+ QCOMPARE(release_count, 10);
}
void tst_QPushButton::touchTap()
{
QTest::touchEvent(testWidget, m_touchScreen).press(0, QPoint(10, 10));
- QVERIFY( press_count == 1 );
- QVERIFY( release_count == 0 );
+ QCOMPARE(press_count, 1);
+ QCOMPARE(release_count, 0);
QTest::touchEvent(testWidget, m_touchScreen).release(0, QPoint(10, 10));
- QCOMPARE( press_count, (uint)1 );
- QCOMPARE( release_count, (uint)1 );
- QCOMPARE( click_count, (uint)1 );
+ QCOMPARE(press_count, 1);
+ QCOMPARE(release_count, 1);
+ QCOMPARE(click_count, 1);
press_count = 0;
release_count = 0;
@@ -411,26 +393,23 @@ void tst_QPushButton::touchTap()
QTest::touchEvent(testWidget, m_touchScreen).press(0, QPoint(10, 10));
QTest::touchEvent(testWidget, m_touchScreen).release(0, QPoint(10, 10));
}
- QCOMPARE( press_count, (uint)10 );
- QCOMPARE( release_count, (uint)10 );
- QCOMPARE( click_count, (uint)10 );
-}
-
-QPushButton *pb = 0;
-void tst_QPushButton::helperSlotDelete()
-{
- delete pb;
- pb = 0;
+ QCOMPARE(press_count, 10);
+ QCOMPARE(release_count, 10);
+ QCOMPARE(click_count, 10);
}
void tst_QPushButton::popupCrash()
{
- pb = new QPushButton("foo");
+ QPushButton *pb = new QPushButton("foo");
QMenu *menu = new QMenu("bar", pb);
pb->setMenu(menu);
- QTimer::singleShot(1000, this, SLOT(helperSlotDelete()));
+ QTimer::singleShot(1000, this, [&pb]{
+ delete pb;
+ pb = nullptr;
+ });
pb->show();
pb->click();
+ QTRY_COMPARE(pb, nullptr);
}
void tst_QPushButton::defaultAndAutoDefault()
@@ -520,14 +499,14 @@ void tst_QPushButton::defaultAndAutoDefault()
// Reparenting
QVERIFY(button2.autoDefault());
- button2.setParent(0);
+ button2.setParent(nullptr);
QVERIFY(!button2.autoDefault());
button2.setAutoDefault(false);
button2.setParent(&dialog);
QVERIFY(!button2.autoDefault());
button1.setAutoDefault(true);
- button1.setParent(0);
+ button1.setParent(nullptr);
QVERIFY(button1.autoDefault());
}
}
@@ -568,7 +547,7 @@ void tst_QPushButton::sizeHint()
button->setParent(widget);
button->sizeHint();
- widget->setParent(0);
+ widget->setParent(nullptr);
delete dialog;
button->setDefault(false);
QCOMPARE(button->sizeHint(), initSizeHint);
@@ -623,7 +602,7 @@ void tst_QPushButton::taskQTBUG_20191_shortcutWithKeypadModifer()
dialog.setLayout(layout);
dialog.show();
QVERIFY(QTest::qWaitForWindowExposed(&dialog));
- QApplication::setActiveWindow(&dialog);
+ QApplicationPrivate::setActiveWindow(&dialog);
// add shortcut '5' to button1 and test with keyboard and keypad '5' keys
QSignalSpy spy1(button1, SIGNAL(clicked()));
@@ -632,7 +611,7 @@ void tst_QPushButton::taskQTBUG_20191_shortcutWithKeypadModifer()
QTest::qWait(300);
QTest::keyClick(&dialog, Qt::Key_5, Qt::KeypadModifier);
QTest::qWait(300);
- QCOMPARE(spy1.count(), 2);
+ QCOMPARE(spy1.size(), 2);
// add shortcut 'keypad 5' to button2
spy1.clear();
@@ -642,8 +621,8 @@ void tst_QPushButton::taskQTBUG_20191_shortcutWithKeypadModifer()
QTest::qWait(300);
QTest::keyClick(&dialog, Qt::Key_5, Qt::KeypadModifier);
QTest::qWait(300);
- QCOMPARE(spy1.count(), 1);
- QCOMPARE(spy2.count(), 1);
+ QCOMPARE(spy1.size(), 1);
+ QCOMPARE(spy2.size(), 1);
// remove shortcut from button1
spy1.clear();
@@ -653,8 +632,8 @@ void tst_QPushButton::taskQTBUG_20191_shortcutWithKeypadModifer()
QTest::qWait(300);
QTest::keyClick(&dialog, Qt::Key_5, Qt::KeypadModifier);
QTest::qWait(300);
- QCOMPARE(spy1.count(), 0);
- QCOMPARE(spy2.count(), 1);
+ QCOMPARE(spy1.size(), 0);
+ QCOMPARE(spy2.size(), 1);
}
#endif // QT_CONFIG(shortcut)
@@ -670,7 +649,7 @@ void tst_QPushButton::emitReleasedAfterChange()
dialog.setLayout(layout);
dialog.show();
QVERIFY(QTest::qWaitForWindowExposed(&dialog));
- QApplication::setActiveWindow(&dialog);
+ QApplicationPrivate::setActiveWindow(&dialog);
button1->setFocus();
QSignalSpy spy(button1, SIGNAL(released()));
@@ -678,16 +657,16 @@ void tst_QPushButton::emitReleasedAfterChange()
QVERIFY(button1->isDown());
QTest::keyClick(&dialog, Qt::Key_Tab);
QVERIFY(!button1->isDown());
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
button1->setFocus();
QTest::mousePress(button1, Qt::LeftButton);
QVERIFY(button1->isDown());
button1->setEnabled(false);
QVERIFY(!button1->isDown());
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
}
/*
@@ -753,5 +732,81 @@ void tst_QPushButton::iconOnlyStyleSheet()
QVERIFY(QTest::qWaitForWindowExposed(&pb));
}
+/*
+ Test that mouse has been pressed,the signal is sent when moving the mouse.
+ QTBUG-97937
+*/
+void tst_QPushButton::mousePressAndMove()
+{
+ QPushButton button;
+ button.setGeometry(0, 0, 20, 20);
+ QSignalSpy pressSpy(&button, &QAbstractButton::pressed);
+ QSignalSpy releaseSpy(&button, &QAbstractButton::released);
+
+ QTest::mousePress(&button, Qt::LeftButton);
+ QCOMPARE(pressSpy.size(), 1);
+ QCOMPARE(releaseSpy.size(), 0);
+
+ // mouse pressed and moving out
+ QTest::mouseMove(&button, QPoint(100, 100));
+
+ // should emit released signal when the mouse is dragged out of boundary
+ QCOMPARE(pressSpy.size(), 1);
+ QCOMPARE(releaseSpy.size(), 1);
+
+ // mouse pressed and moving into
+ QTest::mouseMove(&button, QPoint(10, 10));
+
+ // should emit pressed signal when the mouse is dragged into of boundary
+ QCOMPARE(pressSpy.size(), 2);
+ QCOMPARE(releaseSpy.size(), 1);
+}
+
+/*
+ Test checking that a QPushButton with a QMenu has a sunken style only
+ when the menu is open
+ QTBUG-120976
+*/
+void tst_QPushButton::reactToMenuClosed()
+{
+ // create a subclass of QPushButton to expose the initStyleOption method
+ class PushButton : public QPushButton {
+ public:
+ virtual void initStyleOption(QStyleOptionButton *option) const override
+ {
+ QPushButton::initStyleOption(option);
+ }
+ };
+
+ PushButton button;
+ QStyleOptionButton opt;
+ QMenu menu;
+
+ // add a menu to the button
+ menu.addAction(tr("string"));
+ button.setMenu(&menu);
+
+ // give the button a size and show it
+ button.setGeometry(0, 0, 50, 50);
+ button.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&button));
+
+ // click the button to open the menu
+ QTest::mouseClick(&button, Qt::LeftButton);
+
+ // check the menu is visible and the button style is sunken
+ QTRY_VERIFY(menu.isVisible());
+ button.initStyleOption(&opt);
+ QVERIFY(opt.state.testFlag(QStyle::StateFlag::State_Sunken));
+
+ // close the menu
+ menu.close();
+
+ // check the menu isn't visible and the style isn't sunken
+ QTRY_VERIFY(!menu.isVisible());
+ button.initStyleOption(&opt);
+ QVERIFY(!opt.state.testFlag(QStyle::StateFlag::State_Sunken));
+}
+
QTEST_MAIN(tst_QPushButton)
#include "tst_qpushbutton.moc"
diff --git a/tests/auto/widgets/widgets/qradiobutton/CMakeLists.txt b/tests/auto/widgets/widgets/qradiobutton/CMakeLists.txt
index 8ce8aadea8..ce016975c8 100644
--- a/tests/auto/widgets/widgets/qradiobutton/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qradiobutton/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qradiobutton.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qradiobutton Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qradiobutton LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qradiobutton
SOURCES
tst_qradiobutton.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
)
diff --git a/tests/auto/widgets/widgets/qradiobutton/tst_qradiobutton.cpp b/tests/auto/widgets/widgets/qradiobutton/tst_qradiobutton.cpp
index 8b1670ae06..144d91e9f2 100644
--- a/tests/auto/widgets/widgets/qradiobutton/tst_qradiobutton.cpp
+++ b/tests/auto/widgets/widgets/qradiobutton/tst_qradiobutton.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>
diff --git a/tests/auto/widgets/widgets/qrhiwidget/CMakeLists.txt b/tests/auto/widgets/widgets/qrhiwidget/CMakeLists.txt
new file mode 100644
index 0000000000..f8d18bcf53
--- /dev/null
+++ b/tests/auto/widgets/widgets/qrhiwidget/CMakeLists.txt
@@ -0,0 +1,25 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qrhiwidget LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+file(GLOB_RECURSE qrhiwidget_resource_files
+ RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
+ data/*
+)
+
+qt_internal_add_test(tst_qrhiwidget
+ SOURCES
+ tst_qrhiwidget.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::Gui
+ Qt::GuiPrivate
+ Qt::Widgets
+ TESTDATA ${qrhiwidget_resource_files}
+ BUILTIN_TESTDATA
+)
diff --git a/tests/auto/widgets/widgets/qrhiwidget/data/simple.frag b/tests/auto/widgets/widgets/qrhiwidget/data/simple.frag
new file mode 100644
index 0000000000..2aa500e09a
--- /dev/null
+++ b/tests/auto/widgets/widgets/qrhiwidget/data/simple.frag
@@ -0,0 +1,8 @@
+#version 440
+
+layout(location = 0) out vec4 fragColor;
+
+void main()
+{
+ fragColor = vec4(1.0, 0.0, 0.0, 1.0);
+}
diff --git a/tests/auto/widgets/widgets/qrhiwidget/data/simple.frag.qsb b/tests/auto/widgets/widgets/qrhiwidget/data/simple.frag.qsb
new file mode 100644
index 0000000000..40d0a296ac
--- /dev/null
+++ b/tests/auto/widgets/widgets/qrhiwidget/data/simple.frag.qsb
Binary files differ
diff --git a/tests/auto/widgets/widgets/qrhiwidget/data/simple.vert b/tests/auto/widgets/widgets/qrhiwidget/data/simple.vert
new file mode 100644
index 0000000000..6b954cdaec
--- /dev/null
+++ b/tests/auto/widgets/widgets/qrhiwidget/data/simple.vert
@@ -0,0 +1,8 @@
+#version 440
+
+layout(location = 0) in vec4 position;
+
+void main()
+{
+ gl_Position = position;
+}
diff --git a/tests/auto/widgets/widgets/qrhiwidget/data/simple.vert.qsb b/tests/auto/widgets/widgets/qrhiwidget/data/simple.vert.qsb
new file mode 100644
index 0000000000..5b7fd39668
--- /dev/null
+++ b/tests/auto/widgets/widgets/qrhiwidget/data/simple.vert.qsb
Binary files differ
diff --git a/tests/auto/widgets/widgets/qrhiwidget/tst_qrhiwidget.cpp b/tests/auto/widgets/widgets/qrhiwidget/tst_qrhiwidget.cpp
new file mode 100644
index 0000000000..7a102180e7
--- /dev/null
+++ b/tests/auto/widgets/widgets/qrhiwidget/tst_qrhiwidget.cpp
@@ -0,0 +1,834 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtWidgets/QRhiWidget>
+#include <QtGui/QPainter>
+#include <QTest>
+#include <QSignalSpy>
+#include <private/qguiapplication_p.h>
+#include <qpa/qplatformintegration.h>
+#include <rhi/qrhi.h>
+
+#include <QApplication>
+#include <QFile>
+#include <QVBoxLayout>
+#include <QScrollArea>
+
+#if QT_CONFIG(vulkan)
+#include <private/qvulkandefaultinstance_p.h>
+#endif
+
+class tst_QRhiWidget : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void initTestCase();
+ void create_data();
+ void create();
+ void noCreate();
+ void simple_data();
+ void simple();
+ void msaa_data();
+ void msaa();
+ void fixedSize_data();
+ void fixedSize();
+ void autoRt_data();
+ void autoRt();
+ void reparent_data();
+ void reparent();
+ void grabFramebufferWhileStillInvisible_data();
+ void grabFramebufferWhileStillInvisible();
+ void grabViaQWidgetGrab_data();
+ void grabViaQWidgetGrab();
+ void mirror_data();
+ void mirror();
+
+private:
+ void testData();
+};
+
+void tst_QRhiWidget::initTestCase()
+{
+ if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::RhiBasedRendering))
+ QSKIP("RhiBasedRendering capability is reported as unsupported on this platform.");
+
+ qputenv("QT_RHI_LEAK_CHECK", "1");
+}
+
+void tst_QRhiWidget::testData()
+{
+ QTest::addColumn<QRhiWidget::Api>("api");
+
+#ifndef Q_OS_WEBOS
+ QTest::newRow("Null") << QRhiWidget::Api::Null;
+#endif
+
+#if QT_CONFIG(opengl)
+ if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL))
+ QTest::newRow("OpenGL") << QRhiWidget::Api::OpenGL;
+#endif
+
+#if QT_CONFIG(vulkan)
+ // Have to probe to be sure Vulkan is actually working (the test cases
+ // themselves will assume QRhi init succeeds).
+ if (QVulkanDefaultInstance::instance()) {
+ QRhiVulkanInitParams vulkanInitParams;
+ vulkanInitParams.inst = QVulkanDefaultInstance::instance();
+ if (QRhi::probe(QRhi::Vulkan, &vulkanInitParams))
+ QTest::newRow("Vulkan") << QRhiWidget::Api::Vulkan;
+ }
+#endif
+
+#if QT_CONFIG(metal)
+ QRhiMetalInitParams metalInitParams;
+ if (QRhi::probe(QRhi::Metal, &metalInitParams))
+ QTest::newRow("Metal") << QRhiWidget::Api::Metal;
+#endif
+
+#ifdef Q_OS_WIN
+ QTest::newRow("D3D11") << QRhiWidget::Api::Direct3D11;
+ // D3D12 needs to be probed too due to being disabled if the SDK headers
+ // are too old (clang, mingw).
+ QRhiD3D12InitParams d3d12InitParams;
+ if (QRhi::probe(QRhi::D3D12, &d3d12InitParams))
+ QTest::newRow("D3D12") << QRhiWidget::Api::Direct3D12;
+#endif
+}
+
+void tst_QRhiWidget::create_data()
+{
+ testData();
+}
+
+void tst_QRhiWidget::create()
+{
+ QFETCH(QRhiWidget::Api, api);
+
+ {
+ QRhiWidget w;
+ w.setApi(api);
+ w.resize(320, 240);
+ w.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&w));
+ }
+
+ {
+ QWidget topLevel;
+ topLevel.resize(320, 240);
+ QRhiWidget *w = new QRhiWidget(&topLevel);
+ w->setApi(api);
+ w->resize(100, 100);
+ topLevel.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
+ }
+}
+
+void tst_QRhiWidget::noCreate()
+{
+ // Now try something that is guaranteed to fail.
+ // E.g. try using Metal on Windows.
+ // The error signal should be emitted. The frame signal should not.
+#ifdef Q_OS_WIN
+ qDebug("Warnings will be printed below, this is as expected");
+ QRhiWidget rhiWidget;
+ rhiWidget.setApi(QRhiWidget::Api::Metal);
+ QSignalSpy frameSpy(&rhiWidget, &QRhiWidget::frameSubmitted);
+ QSignalSpy errorSpy(&rhiWidget, &QRhiWidget::renderFailed);
+ rhiWidget.resize(320, 240);
+ rhiWidget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&rhiWidget));
+ QTRY_VERIFY(errorSpy.count() > 0);
+ QCOMPARE(frameSpy.count(), 0);
+#endif
+}
+
+static QShader getShader(const QString &name)
+{
+ QFile f(name);
+ return f.open(QIODevice::ReadOnly) ? QShader::fromSerialized(f.readAll()) : QShader();
+}
+
+static bool submitResourceUpdates(QRhi *rhi, QRhiResourceUpdateBatch *batch)
+{
+ QRhiCommandBuffer *cb = nullptr;
+ QRhi::FrameOpResult result = rhi->beginOffscreenFrame(&cb);
+ if (result != QRhi::FrameOpSuccess) {
+ qWarning("beginOffscreenFrame returned %d", result);
+ return false;
+ }
+ if (!cb) {
+ qWarning("No command buffer from beginOffscreenFrame");
+ return false;
+ }
+ cb->resourceUpdate(batch);
+ rhi->endOffscreenFrame();
+ return true;
+}
+
+inline bool imageRGBAEquals(const QImage &a, const QImage &b, int maxFuzz = 1)
+{
+ if (a.size() != b.size())
+ return false;
+
+ const QImage image0 = a.convertToFormat(QImage::Format_RGBA8888_Premultiplied);
+ const QImage image1 = b.convertToFormat(QImage::Format_RGBA8888_Premultiplied);
+
+ const int width = image0.width();
+ const int height = image0.height();
+ for (int y = 0; y < height; ++y) {
+ const quint32 *p0 = reinterpret_cast<const quint32 *>(image0.constScanLine(y));
+ const quint32 *p1 = reinterpret_cast<const quint32 *>(image1.constScanLine(y));
+ int x = width - 1;
+ while (x-- >= 0) {
+ const QRgb c0(*p0++);
+ const QRgb c1(*p1++);
+ const int red = qAbs(qRed(c0) - qRed(c1));
+ const int green = qAbs(qGreen(c0) - qGreen(c1));
+ const int blue = qAbs(qBlue(c0) - qBlue(c1));
+ const int alpha = qAbs(qAlpha(c0) - qAlpha(c1));
+ if (red > maxFuzz || green > maxFuzz || blue > maxFuzz || alpha > maxFuzz)
+ return false;
+ }
+ }
+
+ return true;
+}
+
+class SimpleRhiWidget : public QRhiWidget
+{
+public:
+ SimpleRhiWidget(int sampleCount = 1, QWidget *parent = nullptr)
+ : QRhiWidget(parent),
+ m_sampleCount(sampleCount)
+ { }
+
+ ~SimpleRhiWidget()
+ {
+ delete m_rt;
+ delete m_rp;
+ }
+
+ void initialize(QRhiCommandBuffer *cb) override;
+ void render(QRhiCommandBuffer *cb) override;
+ void releaseResources() override;
+
+ int m_sampleCount;
+ QRhi *m_rhi = nullptr;
+ std::unique_ptr<QRhiBuffer> m_vbuf;
+ std::unique_ptr<QRhiBuffer> m_ubuf;
+ std::unique_ptr<QRhiShaderResourceBindings> m_srb;
+ std::unique_ptr<QRhiGraphicsPipeline> m_pipeline;
+ QRhiTextureRenderTarget *m_rt = nullptr; // used when autoRenderTarget is off
+ QRhiRenderPassDescriptor *m_rp = nullptr; // used when autoRenderTarget is off
+
+ friend class tst_QRhiWidget;
+};
+
+void SimpleRhiWidget::initialize(QRhiCommandBuffer *cb)
+{
+ if (m_rhi != rhi()) {
+ m_pipeline.reset();
+ m_rhi = rhi();
+ }
+
+ if (!m_pipeline) {
+ if (!isAutoRenderTargetEnabled()) {
+ delete m_rt;
+ delete m_rp;
+ QRhiTextureRenderTargetDescription rtDesc;
+ if (colorTexture()) {
+ rtDesc.setColorAttachments({ colorTexture() });
+ } else if (msaaColorBuffer()) {
+ QRhiColorAttachment att;
+ att.setRenderBuffer(msaaColorBuffer());
+ rtDesc.setColorAttachments({ att });
+ }
+ m_rt = m_rhi->newTextureRenderTarget(rtDesc);
+ m_rp = m_rt->newCompatibleRenderPassDescriptor();
+ m_rt->setRenderPassDescriptor(m_rp);
+ m_rt->create();
+ }
+
+ static float vertexData[] = {
+ 0, 1,
+ -1, -1,
+ 1, -1
+ };
+
+ m_vbuf.reset(m_rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(vertexData)));
+ m_vbuf->create();
+
+ m_ubuf.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 64));
+ m_ubuf->create();
+
+ m_srb.reset(m_rhi->newShaderResourceBindings());
+ m_srb->create();
+
+ m_pipeline.reset(m_rhi->newGraphicsPipeline());
+ m_pipeline->setShaderStages({
+ { QRhiShaderStage::Vertex, getShader(QLatin1String(":/data/simple.vert.qsb")) },
+ { QRhiShaderStage::Fragment, getShader(QLatin1String(":/data/simple.frag.qsb")) }
+ });
+ QRhiVertexInputLayout inputLayout;
+ inputLayout.setBindings({
+ { 2 * sizeof(float) }
+ });
+ inputLayout.setAttributes({
+ { 0, 0, QRhiVertexInputAttribute::Float2, 0 }
+ });
+ m_pipeline->setSampleCount(m_sampleCount);
+ m_pipeline->setVertexInputLayout(inputLayout);
+ m_pipeline->setShaderResourceBindings(m_srb.get());
+ m_pipeline->setRenderPassDescriptor(renderTarget() ? renderTarget()->renderPassDescriptor() : m_rp);
+ m_pipeline->create();
+
+ QRhiResourceUpdateBatch *resourceUpdates = m_rhi->nextResourceUpdateBatch();
+ resourceUpdates->uploadStaticBuffer(m_vbuf.get(), vertexData);
+ cb->resourceUpdate(resourceUpdates);
+ }
+}
+
+void SimpleRhiWidget::render(QRhiCommandBuffer *cb)
+{
+ const QSize outputSize = colorTexture() ? colorTexture()->pixelSize() : msaaColorBuffer()->pixelSize();
+ if (renderTarget()) {
+ QCOMPARE(outputSize, renderTarget()->pixelSize());
+ if (rhi()->backend() != QRhi::Null && rhi()->supportedSampleCounts().contains(m_sampleCount))
+ QCOMPARE(m_sampleCount, renderTarget()->sampleCount());
+ }
+
+ const QColor clearColor = QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f);
+ cb->beginPass(renderTarget() ? renderTarget() : m_rt, clearColor, { 1.0f, 0 });
+ cb->setGraphicsPipeline(m_pipeline.get());
+ cb->setViewport(QRhiViewport(0, 0, outputSize.width(), outputSize.height()));
+ cb->setShaderResources();
+ const QRhiCommandBuffer::VertexInput vbufBinding(m_vbuf.get(), 0);
+ cb->setVertexInput(0, 1, &vbufBinding);
+ cb->draw(3);
+ cb->endPass();
+}
+
+void SimpleRhiWidget::releaseResources()
+{
+ m_pipeline.reset();
+ m_srb.reset();
+ m_ubuf.reset();
+ m_vbuf.reset();
+
+}
+
+void tst_QRhiWidget::simple_data()
+{
+ testData();
+}
+
+void tst_QRhiWidget::simple()
+{
+ QFETCH(QRhiWidget::Api, api);
+
+ SimpleRhiWidget *rhiWidget = new SimpleRhiWidget;
+ rhiWidget->setApi(api);
+ QSignalSpy frameSpy(rhiWidget, &QRhiWidget::frameSubmitted);
+ QSignalSpy errorSpy(rhiWidget, &QRhiWidget::renderFailed);
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addWidget(rhiWidget);
+
+ QWidget w;
+ w.setLayout(layout);
+ w.resize(1280, 720);
+ w.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&w));
+
+ QTRY_VERIFY(frameSpy.count() > 0);
+ QCOMPARE(errorSpy.count(), 0);
+
+ QCOMPARE(rhiWidget->sampleCount(), 1);
+ QCOMPARE(rhiWidget->colorBufferFormat(), QRhiWidget::TextureFormat::RGBA8);
+ QVERIFY(rhiWidget->isAutoRenderTargetEnabled());
+
+ // Pull out the QRhiTexture (we know colorTexture() and rhi() and friends
+ // are all there even outside initialize() and render(), even though this
+ // is not quite documented), and read it back.
+ QRhiTexture *backingTexture = rhiWidget->colorTexture();
+ QVERIFY(backingTexture);
+ QCOMPARE(backingTexture->format(), QRhiTexture::RGBA8);
+ QVERIFY(rhiWidget->depthStencilBuffer());
+ QVERIFY(rhiWidget->renderTarget());
+ QVERIFY(!rhiWidget->resolveTexture());
+ QRhi *rhi = rhiWidget->rhi();
+ QVERIFY(rhi);
+
+ switch (api) {
+ case QRhiWidget::Api::OpenGL:
+ QCOMPARE(rhi->backend(), QRhi::OpenGLES2);
+ break;
+ case QRhiWidget::Api::Metal:
+ QCOMPARE(rhi->backend(), QRhi::Metal);
+ break;
+ case QRhiWidget::Api::Vulkan:
+ QCOMPARE(rhi->backend(), QRhi::Vulkan);
+ break;
+ case QRhiWidget::Api::Direct3D11:
+ QCOMPARE(rhi->backend(), QRhi::D3D11);
+ break;
+ case QRhiWidget::Api::Direct3D12:
+ QCOMPARE(rhi->backend(), QRhi::D3D12);
+ break;
+ case QRhiWidget::Api::Null:
+ QCOMPARE(rhi->backend(), QRhi::Null);
+ break;
+ default:
+ break;
+ }
+
+ const int maxFuzz = 1;
+ QImage resultOne;
+ if (rhi->backend() != QRhi::Null) {
+ QRhiReadbackResult readResult;
+ bool readCompleted = false;
+ readResult.completed = [&readCompleted] { readCompleted = true; };
+ QRhiResourceUpdateBatch *rub = rhi->nextResourceUpdateBatch();
+ rub->readBackTexture(backingTexture, &readResult);
+ QVERIFY(submitResourceUpdates(rhi, rub));
+ QVERIFY(readCompleted);
+
+ QImage wrapperImage(reinterpret_cast<const uchar *>(readResult.data.constData()),
+ readResult.pixelSize.width(), readResult.pixelSize.height(),
+ QImage::Format_RGBA8888);
+ if (rhi->isYUpInFramebuffer())
+ resultOne = wrapperImage.mirrored();
+ else
+ resultOne = wrapperImage.copy();
+
+ // result is now a red triangle upon greenish background, where the
+ // triangle's edges are (0, 1), (-1, -1), and (1, -1).
+ // It's upside down with Vulkan (Y is not corrected, clipSpaceCorrMatrix() is not used),
+ // but that won't matter for the test.
+
+ // Check that the center is a red pixel.
+ QRgb c = resultOne.pixel(resultOne.width() / 2, resultOne.height() / 2);
+ QVERIFY(qRed(c) >= 255 - maxFuzz);
+ QVERIFY(qGreen(c) <= maxFuzz);
+ QVERIFY(qBlue(c) <= maxFuzz);
+ }
+
+ // Now through grabFramebuffer().
+ QImage resultTwo;
+ if (rhi->backend() != QRhi::Null) {
+ resultTwo = rhiWidget->grabFramebuffer();
+ QCOMPARE(errorSpy.count(), 0);
+ QVERIFY(!resultTwo.isNull());
+ QRgb c = resultTwo.pixel(resultTwo.width() / 2, resultTwo.height() / 2);
+ QVERIFY(qRed(c) >= 255 - maxFuzz);
+ QVERIFY(qGreen(c) <= maxFuzz);
+ QVERIFY(qBlue(c) <= maxFuzz);
+ }
+
+ // Check we got the same result from our manual readback and when the
+ // texture was rendered to again and grabFramebuffer() was called.
+ QVERIFY(imageRGBAEquals(resultOne, resultTwo, maxFuzz));
+}
+
+void tst_QRhiWidget::msaa_data()
+{
+ testData();
+}
+
+void tst_QRhiWidget::msaa()
+{
+ QFETCH(QRhiWidget::Api, api);
+
+ const int SAMPLE_COUNT = 4;
+ SimpleRhiWidget *rhiWidget = new SimpleRhiWidget(SAMPLE_COUNT);
+ rhiWidget->setApi(api);
+ rhiWidget->setSampleCount(SAMPLE_COUNT);
+ QSignalSpy frameSpy(rhiWidget, &QRhiWidget::frameSubmitted);
+ QSignalSpy errorSpy(rhiWidget, &QRhiWidget::renderFailed);
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addWidget(rhiWidget);
+
+ QWidget w;
+ w.setLayout(layout);
+ w.resize(1280, 720);
+ w.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&w));
+
+ QTRY_VERIFY(frameSpy.count() > 0);
+ QCOMPARE(errorSpy.count(), 0);
+
+ QCOMPARE(rhiWidget->sampleCount(), 4);
+ QCOMPARE(rhiWidget->colorBufferFormat(), QRhiWidget::TextureFormat::RGBA8);
+ QVERIFY(!rhiWidget->colorTexture());
+ QVERIFY(rhiWidget->msaaColorBuffer());
+ QVERIFY(rhiWidget->depthStencilBuffer());
+ QVERIFY(rhiWidget->renderTarget());
+ QVERIFY(rhiWidget->resolveTexture());
+ QCOMPARE(rhiWidget->resolveTexture()->format(), QRhiTexture::RGBA8);
+ QRhi *rhi = rhiWidget->rhi();
+ QVERIFY(rhi);
+
+ if (rhi->backend() != QRhi::Null) {
+ QRhiReadbackResult readResult;
+ QRhiResourceUpdateBatch *rub = rhi->nextResourceUpdateBatch();
+ rub->readBackTexture(rhiWidget->resolveTexture(), &readResult);
+ QVERIFY(submitResourceUpdates(rhi, rub));
+
+ QImage wrapperImage(reinterpret_cast<const uchar *>(readResult.data.constData()),
+ readResult.pixelSize.width(), readResult.pixelSize.height(),
+ QImage::Format_RGBA8888);
+ QImage result;
+ if (rhi->isYUpInFramebuffer())
+ result = wrapperImage.mirrored();
+ else
+ result = wrapperImage.copy();
+
+ // Check that the center is a red pixel.
+ const int maxFuzz = 1;
+ QRgb c = result.pixel(result.width() / 2, result.height() / 2);
+ QVERIFY(qRed(c) >= 255 - maxFuzz);
+ QVERIFY(qGreen(c) <= maxFuzz);
+ QVERIFY(qBlue(c) <= maxFuzz);
+ }
+
+ // See if switching back and forth works.
+ frameSpy.clear();
+ rhiWidget->m_pipeline.reset();
+ rhiWidget->m_sampleCount = 1;
+ rhiWidget->setSampleCount(1);
+ QTRY_VERIFY(frameSpy.count() > 0);
+ QCOMPARE(errorSpy.count(), 0);
+ QVERIFY(rhiWidget->colorTexture());
+ QVERIFY(!rhiWidget->msaaColorBuffer());
+
+ frameSpy.clear();
+ rhiWidget->m_pipeline.reset();
+ rhiWidget->m_sampleCount = SAMPLE_COUNT;
+ rhiWidget->setSampleCount(SAMPLE_COUNT);
+ QTRY_VERIFY(frameSpy.count() > 0);
+ QCOMPARE(errorSpy.count(), 0);
+ QVERIFY(!rhiWidget->colorTexture());
+ QVERIFY(rhiWidget->msaaColorBuffer());
+}
+
+void tst_QRhiWidget::fixedSize_data()
+{
+ testData();
+}
+
+void tst_QRhiWidget::fixedSize()
+{
+ QFETCH(QRhiWidget::Api, api);
+
+ SimpleRhiWidget *rhiWidget = new SimpleRhiWidget;
+ rhiWidget->setApi(api);
+ QSignalSpy frameSpy(rhiWidget, &QRhiWidget::frameSubmitted);
+ QSignalSpy errorSpy(rhiWidget, &QRhiWidget::renderFailed);
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addWidget(rhiWidget);
+
+ rhiWidget->setFixedColorBufferSize(QSize(320, 200));
+
+ QWidget w;
+ w.setLayout(layout);
+ w.resize(1280, 720);
+ w.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&w));
+
+ QTRY_VERIFY(frameSpy.count() > 0);
+ QCOMPARE(errorSpy.count(), 0);
+
+ QVERIFY(rhiWidget->rhi());
+ QVERIFY(rhiWidget->colorTexture());
+ QCOMPARE(rhiWidget->colorTexture()->pixelSize(), QSize(320, 200));
+ QVERIFY(rhiWidget->depthStencilBuffer());
+ QCOMPARE(rhiWidget->depthStencilBuffer()->pixelSize(), QSize(320, 200));
+ QVERIFY(rhiWidget->renderTarget());
+ QVERIFY(!rhiWidget->resolveTexture());
+
+ frameSpy.clear();
+ rhiWidget->setFixedColorBufferSize(640, 480); // should also trigger update()
+ QTRY_VERIFY(frameSpy.count() > 0);
+
+ QVERIFY(rhiWidget->colorTexture());
+ QCOMPARE(rhiWidget->colorTexture()->pixelSize(), QSize(640, 480));
+ QVERIFY(rhiWidget->depthStencilBuffer());
+ QCOMPARE(rhiWidget->depthStencilBuffer()->pixelSize(), QSize(640, 480));
+
+ frameSpy.clear();
+ rhiWidget->setFixedColorBufferSize(QSize());
+ QTRY_VERIFY(frameSpy.count() > 0);
+
+ QVERIFY(rhiWidget->colorTexture());
+ QVERIFY(rhiWidget->colorTexture()->pixelSize() != QSize(640, 480));
+ QVERIFY(rhiWidget->depthStencilBuffer());
+ QVERIFY(rhiWidget->depthStencilBuffer()->pixelSize() != QSize(640, 480));
+}
+
+void tst_QRhiWidget::autoRt_data()
+{
+ testData();
+}
+
+void tst_QRhiWidget::autoRt()
+{
+ QFETCH(QRhiWidget::Api, api);
+
+ SimpleRhiWidget *rhiWidget = new SimpleRhiWidget;
+ rhiWidget->setApi(api);
+ QVERIFY(rhiWidget->isAutoRenderTargetEnabled());
+ rhiWidget->setAutoRenderTarget(false);
+ QVERIFY(!rhiWidget->isAutoRenderTargetEnabled());
+ QSignalSpy frameSpy(rhiWidget, &QRhiWidget::frameSubmitted);
+ QSignalSpy errorSpy(rhiWidget, &QRhiWidget::renderFailed);
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addWidget(rhiWidget);
+
+ QWidget w;
+ w.setLayout(layout);
+ w.resize(1280, 720);
+ w.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&w));
+
+ QTRY_VERIFY(frameSpy.count() > 0);
+ QCOMPARE(errorSpy.count(), 0);
+
+ QVERIFY(rhiWidget->rhi());
+ QVERIFY(rhiWidget->colorTexture());
+ QVERIFY(!rhiWidget->depthStencilBuffer());
+ QVERIFY(!rhiWidget->renderTarget());
+ QVERIFY(!rhiWidget->resolveTexture());
+
+ QVERIFY(rhiWidget->m_rt);
+ QVERIFY(rhiWidget->m_rp);
+ QCOMPARE(rhiWidget->m_rt->description().cbeginColorAttachments()->texture(), rhiWidget->colorTexture());
+
+ frameSpy.clear();
+ // do something that triggers creating a new backing texture
+ rhiWidget->setFixedColorBufferSize(QSize(320, 200));
+ QTRY_VERIFY(frameSpy.count() > 0);
+
+ QVERIFY(rhiWidget->colorTexture());
+ QCOMPARE(rhiWidget->m_rt->description().cbeginColorAttachments()->texture(), rhiWidget->colorTexture());
+}
+
+void tst_QRhiWidget::reparent_data()
+{
+ testData();
+}
+
+void tst_QRhiWidget::reparent()
+{
+ if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::MultipleWindows))
+ QSKIP("MultipleWindows capability is reported as unsupported, skipping reparenting test.");
+
+ QFETCH(QRhiWidget::Api, api);
+
+ QWidget *windowOne = new QWidget;
+ windowOne->resize(1280, 720);
+
+ SimpleRhiWidget *rhiWidget = new SimpleRhiWidget(1);
+ rhiWidget->setApi(api);
+ rhiWidget->resize(800, 600);
+ QSignalSpy frameSpy(rhiWidget, &QRhiWidget::frameSubmitted);
+ QSignalSpy errorSpy(rhiWidget, &QRhiWidget::renderFailed);
+
+ rhiWidget->show();
+ QVERIFY(QTest::qWaitForWindowExposed(rhiWidget));
+ QTRY_VERIFY(frameSpy.count() > 0);
+ QCOMPARE(errorSpy.count(), 0);
+
+ frameSpy.clear();
+ rhiWidget->setParent(windowOne);
+ windowOne->show();
+ QVERIFY(QTest::qWaitForWindowExposed(windowOne));
+ QTRY_VERIFY(frameSpy.count() > 0);
+ QCOMPARE(errorSpy.count(), 0);
+
+ frameSpy.clear();
+ QWidget windowTwo;
+ windowTwo.resize(1280, 720);
+
+ rhiWidget->setParent(&windowTwo);
+
+ // There's nothing saying the old top-level parent is going to be around,
+ // which is interesting wrt to its QRhi and resources created with that;
+ // exercise this.
+ delete windowOne;
+
+ windowTwo.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&windowTwo));
+ QTRY_VERIFY(frameSpy.count() > 0);
+ QCOMPARE(errorSpy.count(), 0);
+
+ // now reparent after show() has already been called
+ frameSpy.clear();
+ QWidget windowThree;
+ windowThree.resize(1280, 720);
+ windowThree.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&windowThree));
+
+ rhiWidget->setParent(&windowThree);
+ // this case needs a show() on rhiWidget
+ rhiWidget->show();
+
+ QTRY_VERIFY(frameSpy.count() > 0);
+ QCOMPARE(errorSpy.count(), 0);
+}
+
+void tst_QRhiWidget::grabFramebufferWhileStillInvisible_data()
+{
+ testData();
+}
+
+void tst_QRhiWidget::grabFramebufferWhileStillInvisible()
+{
+ QFETCH(QRhiWidget::Api, api);
+
+ const int maxFuzz = 1;
+
+ SimpleRhiWidget w;
+ w.setApi(api);
+ w.resize(1280, 720);
+ QSignalSpy errorSpy(&w, &QRhiWidget::renderFailed);
+
+ QImage image = w.grabFramebuffer(); // creates its own QRhi just to render offscreen
+ QVERIFY(!image.isNull());
+ QVERIFY(w.rhi());
+ QVERIFY(w.colorTexture());
+ QCOMPARE(errorSpy.count(), 0);
+ if (api != QRhiWidget::Api::Null) {
+ QRgb c = image.pixel(image.width() / 2, image.height() / 2);
+ QVERIFY(qRed(c) >= 255 - maxFuzz);
+ QVERIFY(qGreen(c) <= maxFuzz);
+ QVERIFY(qBlue(c) <= maxFuzz);
+ }
+
+ // Make the window visible, this under the hood drops the QRhiWidget's
+ // own QRhi and attaches to the backingstore's.
+ QSignalSpy frameSpy(&w, &QRhiWidget::frameSubmitted);
+ w.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&w));
+ QTRY_VERIFY(frameSpy.count() > 0);
+
+ QCOMPARE(errorSpy.count(), 0);
+
+ if (api != QRhiWidget::Api::Null) {
+ QRhiReadbackResult readResult;
+ QRhiResourceUpdateBatch *rub = w.rhi()->nextResourceUpdateBatch();
+ rub->readBackTexture(w.colorTexture(), &readResult);
+ QVERIFY(submitResourceUpdates(w.rhi(), rub));
+ QImage wrapperImage(reinterpret_cast<const uchar *>(readResult.data.constData()),
+ readResult.pixelSize.width(), readResult.pixelSize.height(),
+ QImage::Format_RGBA8888);
+ if (w.rhi()->isYUpInFramebuffer())
+ image = wrapperImage.mirrored();
+ else
+ image = wrapperImage.copy();
+ QRgb c = image.pixel(image.width() / 2, image.height() / 2);
+ QVERIFY(qRed(c) >= 255 - maxFuzz);
+ QVERIFY(qGreen(c) <= maxFuzz);
+ QVERIFY(qBlue(c) <= maxFuzz);
+ }
+}
+
+void tst_QRhiWidget::grabViaQWidgetGrab_data()
+{
+ testData();
+}
+
+void tst_QRhiWidget::grabViaQWidgetGrab()
+{
+ QFETCH(QRhiWidget::Api, api);
+
+ SimpleRhiWidget w;
+ w.setApi(api);
+ w.resize(1280, 720);
+ QSignalSpy frameSpy(&w, &QRhiWidget::frameSubmitted);
+ w.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&w));
+ QTRY_VERIFY(frameSpy.count() > 0);
+
+ QImage image = w.grab().toImage();
+
+ if (w.rhi()->backend() != QRhi::Null) {
+ // It's upside down with Vulkan (Y is not corrected, clipSpaceCorrMatrix() is not used),
+ // but that won't matter for the test.
+ QRgb c = image.pixel(image.width() / 2, image.height() / 2);
+ const int maxFuzz = 1;
+ QVERIFY(qRed(c) >= 255 - maxFuzz);
+ QVERIFY(qGreen(c) <= maxFuzz);
+ QVERIFY(qBlue(c) <= maxFuzz);
+ }
+}
+
+void tst_QRhiWidget::mirror_data()
+{
+ testData();
+}
+
+void tst_QRhiWidget::mirror()
+{
+ QFETCH(QRhiWidget::Api, api);
+
+ SimpleRhiWidget *rhiWidget = new SimpleRhiWidget;
+ rhiWidget->setApi(api);
+ QVERIFY(!rhiWidget->isMirrorVerticallyEnabled());
+
+ QSignalSpy frameSpy(rhiWidget, &QRhiWidget::frameSubmitted);
+ QSignalSpy errorSpy(rhiWidget, &QRhiWidget::renderFailed);
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addWidget(rhiWidget);
+ QWidget w;
+ w.setLayout(layout);
+ w.resize(1280, 720);
+ w.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&w));
+
+ QTRY_VERIFY(frameSpy.count() > 0);
+ QCOMPARE(errorSpy.count(), 0);
+
+ frameSpy.clear();
+ rhiWidget->setMirrorVertically(true);
+ QVERIFY(rhiWidget->isMirrorVerticallyEnabled());
+ QTRY_VERIFY(frameSpy.count() > 0);
+ QCOMPARE(errorSpy.count(), 0);
+
+ if (api != QRhiWidget::Api::Null) {
+ QRhi *rhi = rhiWidget->rhi();
+ QRhiReadbackResult readResult;
+ QRhiResourceUpdateBatch *rub = rhi->nextResourceUpdateBatch();
+ rub->readBackTexture(rhiWidget->colorTexture(), &readResult);
+ QVERIFY(submitResourceUpdates(rhi, rub));
+ QImage wrapperImage(reinterpret_cast<const uchar *>(readResult.data.constData()),
+ readResult.pixelSize.width(), readResult.pixelSize.height(),
+ QImage::Format_RGBA8888);
+ QImage image;
+ if (rhi->isYUpInFramebuffer())
+ image = wrapperImage.mirrored();
+ else
+ image = wrapperImage.copy();
+
+ const int maxFuzz = 1;
+ QRgb c = image.pixel(50, 5);
+ if (api != QRhiWidget::Api::Vulkan) {
+ // this should be the background (greenish), not the red triangle
+ QVERIFY(qGreen(c) > qRed(c));
+ } else {
+ // remember that Vulkan is upside down due to not correcting for Y down in NDC
+ // hence this is red
+ QVERIFY(qRed(c) >= 255 - maxFuzz);
+ QVERIFY(qGreen(c) <= maxFuzz);
+ }
+ QVERIFY(qBlue(c) <= maxFuzz);
+ }
+}
+
+QTEST_MAIN(tst_QRhiWidget)
+
+#include "tst_qrhiwidget.moc"
diff --git a/tests/auto/widgets/widgets/qscrollarea/CMakeLists.txt b/tests/auto/widgets/widgets/qscrollarea/CMakeLists.txt
index a10c911286..5e84614407 100644
--- a/tests/auto/widgets/widgets/qscrollarea/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qscrollarea/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qscrollarea.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qscrollarea Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qscrollarea LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qscrollarea
SOURCES
tst_qscrollarea.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
)
diff --git a/tests/auto/widgets/widgets/qscrollarea/tst_qscrollarea.cpp b/tests/auto/widgets/widgets/qscrollarea/tst_qscrollarea.cpp
index e0fd42e95c..87a623b223 100644
--- a/tests/auto/widgets/widgets/qscrollarea/tst_qscrollarea.cpp
+++ b/tests/auto/widgets/widgets/qscrollarea/tst_qscrollarea.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>
diff --git a/tests/auto/widgets/widgets/qscrollbar/CMakeLists.txt b/tests/auto/widgets/widgets/qscrollbar/CMakeLists.txt
index fbaba594cf..23e31327e1 100644
--- a/tests/auto/widgets/widgets/qscrollbar/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qscrollbar/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qscrollbar.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qscrollbar Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qscrollbar LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qscrollbar
SOURCES
tst_qscrollbar.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::TestPrivate
Qt::Widgets
diff --git a/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp b/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp
index 471a9bd3e4..fc836dec4a 100644
--- a/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp
+++ b/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.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>
@@ -115,7 +90,7 @@ void tst_QScrollBar::task_209492()
QSignalSpy spy(verticalScrollBar, SIGNAL(actionTriggered(int)));
QCOMPARE(scrollArea.scrollCount, 0);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
// Simulate a mouse click on the "scroll down button".
const QPoint pressPoint(verticalScrollBar->width() / 2, verticalScrollBar->height() - 10);
@@ -134,7 +109,7 @@ void tst_QScrollBar::task_209492()
QSKIP("The result depends on system setting and is not relevant on Mac");
#endif
QCOMPARE(scrollArea.scrollCount, 1);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
}
#if QT_CONFIG(wheelevent)
@@ -184,7 +159,7 @@ void tst_QScrollBar::QTBUG_42871()
QSignalSpy spy(&scrollBarWidget, SIGNAL(actionTriggered(int)));
QVERIFY(spy.isValid());
QCOMPARE(myHandler.updatesCount, 0);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
// Simulate a mouse click on the "scroll down button".
const QPoint pressPoint(scrollBarWidget.width() / 2, scrollBarWidget.height() - 10);
@@ -192,13 +167,20 @@ void tst_QScrollBar::QTBUG_42871()
QMouseEvent mousePressEvent(QEvent::MouseButtonPress, pressPoint, globalPressPoint,
Qt::LeftButton, Qt::LeftButton, {});
QApplication::sendEvent(&scrollBarWidget, &mousePressEvent);
+ QElapsedTimer timer;
+ timer.start();
QTest::qWait(1);
QMouseEvent mouseReleaseEvent(QEvent::MouseButtonRelease, pressPoint, globalPressPoint,
Qt::LeftButton, Qt::LeftButton, {});
QApplication::sendEvent(&scrollBarWidget, &mouseReleaseEvent);
+ if (timer.elapsed() > 40) {
+ // took too long, we need to tolerate auto-repeat
+ if (myHandler.updatesCount > 1)
+ QEXPECT_FAIL("", "Took too long to process events, repeat timer fired", Continue);
+ }
// Check that the action was triggered once.
QCOMPARE(myHandler.updatesCount, 1);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), myHandler.updatesCount);
}
QTEST_MAIN(tst_QScrollBar)
diff --git a/tests/auto/widgets/widgets/qsizegrip/CMakeLists.txt b/tests/auto/widgets/widgets/qsizegrip/CMakeLists.txt
index c05b601d87..2de1583233 100644
--- a/tests/auto/widgets/widgets/qsizegrip/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qsizegrip/CMakeLists.txt
@@ -1,15 +1,20 @@
-# Generated from qsizegrip.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qsizegrip Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsizegrip LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qsizegrip
SOURCES
tst_qsizegrip.cpp
- INCLUDE_DIRECTORIES
- .
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
)
diff --git a/tests/auto/widgets/widgets/qsizegrip/tst_qsizegrip.cpp b/tests/auto/widgets/widgets/qsizegrip/tst_qsizegrip.cpp
index 1c69a1c8bd..a543efe44e 100644
--- a/tests/auto/widgets/widgets/qsizegrip/tst_qsizegrip.cpp
+++ b/tests/auto/widgets/widgets/qsizegrip/tst_qsizegrip.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>
diff --git a/tests/auto/widgets/widgets/qslider/CMakeLists.txt b/tests/auto/widgets/widgets/qslider/CMakeLists.txt
index 4fe495b3c5..664e9a52af 100644
--- a/tests/auto/widgets/widgets/qslider/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qslider/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qslider.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qslider Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qslider LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qslider
SOURCES
tst_qslider.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
)
diff --git a/tests/auto/widgets/widgets/qslider/tst_qslider.cpp b/tests/auto/widgets/widgets/qslider/tst_qslider.cpp
index 3722025782..a70c8c484e 100644
--- a/tests/auto/widgets/widgets/qslider/tst_qslider.cpp
+++ b/tests/auto/widgets/widgets/qslider/tst_qslider.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>
diff --git a/tests/auto/widgets/widgets/qspinbox/BLACKLIST b/tests/auto/widgets/widgets/qspinbox/BLACKLIST
deleted file mode 100644
index 96a7732165..0000000000
--- a/tests/auto/widgets/widgets/qspinbox/BLACKLIST
+++ /dev/null
@@ -1,2 +0,0 @@
-[stepModifierPressAndHold]
-opensuse-42.3
diff --git a/tests/auto/widgets/widgets/qspinbox/CMakeLists.txt b/tests/auto/widgets/widgets/qspinbox/CMakeLists.txt
index adc0ee093f..826ce16d64 100644
--- a/tests/auto/widgets/widgets/qspinbox/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qspinbox/CMakeLists.txt
@@ -1,13 +1,21 @@
-# Generated from qspinbox.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qspinbox Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qspinbox LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qspinbox
SOURCES
tst_qspinbox.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
+ Qt::WidgetsPrivate
)
diff --git a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp
index fc3412f387..dfb0f71139 100644
--- a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp
+++ b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.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 <qdebug.h>
#include <qapplication.h>
@@ -54,6 +29,8 @@
#include <QProxyStyle>
#include <QScreen>
+#include <QtWidgets/private/qapplication_p.h>
+
#if QT_CONFIG(shortcut)
# include <QKeySequence>
#endif
@@ -950,7 +927,7 @@ void tst_QSpinBox::editingFinished()
layout->addWidget(box2);
testFocusWidget.show();
- QApplication::setActiveWindow(&testFocusWidget);
+ QApplicationPrivate::setActiveWindow(&testFocusWidget);
QVERIFY(QTest::qWaitForWindowActive(&testFocusWidget));
box->activateWindow();
box->setFocus();
@@ -964,45 +941,45 @@ void tst_QSpinBox::editingFinished()
QTest::keyClick(box, Qt::Key_Up);
QTest::keyClick(box, Qt::Key_Up);
- QCOMPARE(editingFinishedSpy1.count(), 0);
- QCOMPARE(editingFinishedSpy2.count(), 0);
+ QCOMPARE(editingFinishedSpy1.size(), 0);
+ QCOMPARE(editingFinishedSpy2.size(), 0);
QTest::keyClick(box2, Qt::Key_Up);
QTest::keyClick(box2, Qt::Key_Up);
box2->setFocus();
- QCOMPARE(editingFinishedSpy1.count(), 1);
+ QCOMPARE(editingFinishedSpy1.size(), 1);
box->setFocus();
- QCOMPARE(editingFinishedSpy1.count(), 1);
- QCOMPARE(editingFinishedSpy2.count(), 1);
+ QCOMPARE(editingFinishedSpy1.size(), 1);
+ QCOMPARE(editingFinishedSpy2.size(), 1);
QTest::keyClick(box, Qt::Key_Up);
- QCOMPARE(editingFinishedSpy1.count(), 1);
- QCOMPARE(editingFinishedSpy2.count(), 1);
+ QCOMPARE(editingFinishedSpy1.size(), 1);
+ QCOMPARE(editingFinishedSpy2.size(), 1);
QTest::keyClick(box, Qt::Key_Enter);
- QCOMPARE(editingFinishedSpy1.count(), 2);
- QCOMPARE(editingFinishedSpy2.count(), 1);
+ QCOMPARE(editingFinishedSpy1.size(), 2);
+ QCOMPARE(editingFinishedSpy2.size(), 1);
QTest::keyClick(box, Qt::Key_Return);
- QCOMPARE(editingFinishedSpy1.count(), 3);
- QCOMPARE(editingFinishedSpy2.count(), 1);
+ QCOMPARE(editingFinishedSpy1.size(), 3);
+ QCOMPARE(editingFinishedSpy2.size(), 1);
box2->setFocus();
- QCOMPARE(editingFinishedSpy1.count(), 4);
- QCOMPARE(editingFinishedSpy2.count(), 1);
+ QCOMPARE(editingFinishedSpy1.size(), 4);
+ QCOMPARE(editingFinishedSpy2.size(), 1);
QTest::keyClick(box2, Qt::Key_Enter);
- QCOMPARE(editingFinishedSpy1.count(), 4);
- QCOMPARE(editingFinishedSpy2.count(), 2);
+ QCOMPARE(editingFinishedSpy1.size(), 4);
+ QCOMPARE(editingFinishedSpy2.size(), 2);
QTest::keyClick(box2, Qt::Key_Return);
- QCOMPARE(editingFinishedSpy1.count(), 4);
- QCOMPARE(editingFinishedSpy2.count(), 3);
+ QCOMPARE(editingFinishedSpy1.size(), 4);
+ QCOMPARE(editingFinishedSpy2.size(), 3);
testFocusWidget.hide();
- QCOMPARE(editingFinishedSpy1.count(), 4);
- QCOMPARE(editingFinishedSpy2.count(), 4);
+ QCOMPARE(editingFinishedSpy1.size(), 4);
+ QCOMPARE(editingFinishedSpy2.size(), 4);
//task203285
editingFinishedSpy1.clear();
testFocusWidget.show();
QVERIFY(QTest::qWaitForWindowActive(&testFocusWidget));
box->setKeyboardTracking(false);
- qApp->setActiveWindow(&testFocusWidget);
+ QApplicationPrivate::setActiveWindow(&testFocusWidget);
testFocusWidget.activateWindow();
box->setFocus();
QTRY_VERIFY(box->hasFocus());
@@ -1012,7 +989,7 @@ void tst_QSpinBox::editingFinished()
box2->setFocus();
QTRY_VERIFY(qApp->focusWidget() != box);
QCOMPARE(box->text(), QLatin1String("20"));
- QCOMPARE(editingFinishedSpy1.count(), 1);
+ QCOMPARE(editingFinishedSpy1.size(), 1);
}
void tst_QSpinBox::removeAll()
@@ -1129,7 +1106,7 @@ void tst_QSpinBox::specialValue()
spin.setValue(50);
topWidget.show();
//make sure we have the focus (even if editingFinished fails)
- qApp->setActiveWindow(&topWidget);
+ QApplicationPrivate::setActiveWindow(&topWidget);
topWidget.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&topWidget));
spin.setFocus();
@@ -1175,33 +1152,32 @@ public:
void tst_QSpinBox::sizeHint()
{
- QWidget *widget = new QWidget;
- QHBoxLayout *layout = new QHBoxLayout(widget);
+ QWidget widget;
+ QHBoxLayout *layout = new QHBoxLayout(&widget);
+
sizeHint_SpinBox *spinBox = new sizeHint_SpinBox;
layout->addWidget(spinBox);
- widget->show();
- QVERIFY(QTest::qWaitForWindowExposed(widget));
+ // Make sure all layout requests posted by the QHBoxLayout constructor and addWidget
+ // are processed before the widget is shown
+ QCoreApplication::sendPostedEvents(&widget, QEvent::LayoutRequest);
+ widget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&widget));
// Prefix
spinBox->sizeHintRequests = 0;
spinBox->setPrefix(QLatin1String("abcdefghij"));
- qApp->processEvents();
QTRY_VERIFY(spinBox->sizeHintRequests > 0);
// Suffix
spinBox->sizeHintRequests = 0;
spinBox->setSuffix(QLatin1String("abcdefghij"));
- qApp->processEvents();
QTRY_VERIFY(spinBox->sizeHintRequests > 0);
// Range
spinBox->sizeHintRequests = 0;
spinBox->setRange(0, 1234567890);
spinBox->setValue(spinBox->maximum());
- qApp->processEvents();
QTRY_VERIFY(spinBox->sizeHintRequests > 0);
-
- delete widget;
}
void tst_QSpinBox::taskQTBUG_5008_textFromValueAndValidate()
@@ -1234,7 +1210,7 @@ void tst_QSpinBox::taskQTBUG_5008_textFromValueAndValidate()
spinbox.show();
spinbox.activateWindow();
spinbox.setFocus();
- QApplication::setActiveWindow(&spinbox);
+ QApplicationPrivate::setActiveWindow(&spinbox);
QVERIFY(QTest::qWaitForWindowActive(&spinbox));
QVERIFY(spinbox.hasFocus());
QTRY_COMPARE(static_cast<QWidget *>(&spinbox), QApplication::activeWindow());
@@ -1282,7 +1258,7 @@ void tst_QSpinBox::lineEditReturnPressed()
QSignalSpy spyCurrentChanged(spinBox.lineEdit(), SIGNAL(returnPressed()));
spinBox.show();
QTest::keyClick(&spinBox, Qt::Key_Return);
- QCOMPARE(spyCurrentChanged.count(), 1);
+ QCOMPARE(spyCurrentChanged.size(), 1);
}
void tst_QSpinBox::positiveSign()
@@ -1854,10 +1830,6 @@ void tst_QSpinBox::stepModifierPressAndHold()
spin.setStyle(stepModifierStyle.data());
QSignalSpy spy(&spin, &SpinBox::valueChanged);
- // TODO: remove debug output when QTBUG-69492 is fixed
- connect(&spin, &SpinBox::valueChanged, [=]() {
- qDebug() << QTime::currentTime() << "valueChanged emitted";
- });
spin.show();
QVERIFY(QTest::qWaitForWindowActive(&spin));
@@ -1872,13 +1844,13 @@ void tst_QSpinBox::stepModifierPressAndHold()
qDebug() << "QGuiApplication::focusWindow():" << QGuiApplication::focusWindow();
qDebug() << "QGuiApplication::topLevelWindows():" << QGuiApplication::topLevelWindows();
QTest::mousePress(&spin, Qt::LeftButton, modifiers, buttonRect.center());
- QTRY_VERIFY2(spy.length() >= 3, qPrintable(QString::fromLatin1(
- "Expected valueChanged() to be emitted 3 or more times, but it was only emitted %1 times").arg(spy.length())));
+ QTRY_VERIFY2(spy.size() >= 3, qPrintable(QString::fromLatin1(
+ "Expected valueChanged() to be emitted 3 or more times, but it was only emitted %1 times").arg(spy.size())));
QTest::mouseRelease(&spin, Qt::LeftButton, modifiers, buttonRect.center());
const auto value = spy.last().at(0);
QVERIFY(value.metaType().id() == QMetaType::Int);
- QCOMPARE(value.toInt(), spy.length() * expectedStepModifier);
+ QCOMPARE(value.toInt(), spy.size() * expectedStepModifier);
}
void tst_QSpinBox::stepSelectAll_data()
diff --git a/tests/auto/widgets/widgets/qsplashscreen/CMakeLists.txt b/tests/auto/widgets/widgets/qsplashscreen/CMakeLists.txt
index 7c13db39a2..12602328c3 100644
--- a/tests/auto/widgets/widgets/qsplashscreen/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qsplashscreen/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qsplashscreen.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qsplashscreen Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsplashscreen LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qsplashscreen
SOURCES
tst_qsplashscreen.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
)
diff --git a/tests/auto/widgets/widgets/qsplashscreen/tst_qsplashscreen.cpp b/tests/auto/widgets/widgets/qsplashscreen/tst_qsplashscreen.cpp
index c038682788..f57634152a 100644
--- a/tests/auto/widgets/widgets/qsplashscreen/tst_qsplashscreen.cpp
+++ b/tests/auto/widgets/widgets/qsplashscreen/tst_qsplashscreen.cpp
@@ -1,34 +1,10 @@
-/****************************************************************************
-**
-** 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>
#include <QSplashScreen>
+#include <QTimer>
class tst_QSplashScreen : public QObject
{
@@ -36,7 +12,7 @@ class tst_QSplashScreen : public QObject
private slots:
void checkCloseTime();
- void checkScreenConstructor();
+ void checkConstructorAndShow();
};
class CloseEventSplash : public QSplashScreen
@@ -45,7 +21,7 @@ public:
CloseEventSplash(const QPixmap &pix) : QSplashScreen(pix), receivedCloseEvent(false) {}
bool receivedCloseEvent;
protected:
- void closeEvent(QCloseEvent *event)
+ void closeEvent(QCloseEvent *event) override
{
receivedCloseEvent = true;
QSplashScreen::closeEvent(event);
@@ -60,23 +36,26 @@ void tst_QSplashScreen::checkCloseTime()
QVERIFY(!splash.receivedCloseEvent);
QWidget w;
splash.show();
- QTimer::singleShot(500, &w, SLOT(show()));
+ QTimer::singleShot(10, &w, &QWidget::show);
QVERIFY(!splash.receivedCloseEvent);
splash.finish(&w);
QVERIFY(splash.receivedCloseEvent);
// We check the window handle because if this is not valid, then
// it can't have been exposed
QVERIFY(w.windowHandle());
- QVERIFY(w.windowHandle()->isExposed());
+ QVERIFY(w.windowHandle()->isVisible());
}
-void tst_QSplashScreen::checkScreenConstructor()
+void tst_QSplashScreen::checkConstructorAndShow()
{
- for (const auto screen : QGuiApplication::screens()) {
- QSplashScreen splash(screen);
+ QPixmap pix(100, 100);
+ pix.fill(Qt::red);
+ for (auto *screen : QGuiApplication::screens()) {
+ QSplashScreen splash(screen, pix);
splash.show();
QCOMPARE(splash.screen(), screen);
QVERIFY(splash.windowHandle());
+ QVERIFY(splash.windowHandle()->isVisible());
QCOMPARE(splash.windowHandle()->screen(), screen);
}
}
diff --git a/tests/auto/widgets/widgets/qsplitter/CMakeLists.txt b/tests/auto/widgets/widgets/qsplitter/CMakeLists.txt
index 6cbbfd3792..16244c8834 100644
--- a/tests/auto/widgets/widgets/qsplitter/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qsplitter/CMakeLists.txt
@@ -1,9 +1,16 @@
-# Generated from qsplitter.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qsplitter Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsplitter LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
list(APPEND test_data "extradata.txt")
list(APPEND test_data "setSizes3.dat")
@@ -11,7 +18,7 @@ list(APPEND test_data "setSizes3.dat")
qt_internal_add_test(tst_qsplitter
SOURCES
tst_qsplitter.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
TESTDATA ${test_data}
diff --git a/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp b/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp
index ce7ac0a186..071e6d4cbc 100644
--- a/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp
+++ b/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp
@@ -1,33 +1,10 @@
-/****************************************************************************
-**
-** 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>
+#include <QSignalSpy>
+
#include <qapplication.h>
#include <qsplitter.h>
#include <qstyle.h>
@@ -81,6 +58,8 @@ private slots:
void replaceWidget();
void replaceWidgetWithSplitterChild_data();
void replaceWidgetWithSplitterChild();
+ void replaceWidgetWhileHidden_data();
+ void replaceWidgetWhileHidden();
void handleMinimumWidth();
// task-specific tests below me:
@@ -89,6 +68,7 @@ private slots:
void task169702_sizes();
void taskQTBUG_4101_ensureOneNonCollapsedWidget_data();
void taskQTBUG_4101_ensureOneNonCollapsedWidget();
+ void taskQTBUG_102249_moveNonPressed();
void setLayout();
void autoAdd();
@@ -851,6 +831,47 @@ void tst_QSplitter::replaceWidgetWithSplitterChild()
}
}
+void tst_QSplitter::replaceWidgetWhileHidden_data()
+{
+ QTest::addColumn<bool>("splitterVisible");
+ QTest::addColumn<bool>("widgetVisible");
+
+ QTest::addRow("visibleToVisible") << true << true;
+ QTest::addRow("hiddenToVisible") << true << false;
+ QTest::addRow("visibleToHidden") << false << true;
+ QTest::addRow("hiddenToHidden") << false << false;
+}
+
+void tst_QSplitter::replaceWidgetWhileHidden()
+{
+ QFETCH(bool, splitterVisible);
+ QFETCH(bool, widgetVisible);
+
+ MyFriendlySplitter splitter;
+
+ splitter.addWidget(new QLabel("One"));
+ splitter.addWidget(new QLabel("Two"));
+
+ if (splitterVisible) {
+ splitter.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&splitter));
+ }
+ QWidget *newWidget = new QLabel("Three");
+ if (!widgetVisible)
+ newWidget->hide();
+
+ const bool wasExplicitHide = !widgetVisible && newWidget->testAttribute(Qt::WA_WState_ExplicitShowHide);
+ splitter.replaceWidget(1, newWidget);
+
+ QCOMPARE(!widgetVisible && newWidget->testAttribute(Qt::WA_WState_ExplicitShowHide), wasExplicitHide);
+
+ if (!splitterVisible) {
+ splitter.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&splitter));
+ }
+ QCOMPARE(widgetVisible, newWidget->isVisible());
+}
+
void tst_QSplitter::handleMinimumWidth()
{
MyFriendlySplitter split;
@@ -887,55 +908,56 @@ void tst_QSplitter::rubberBandNotInSplitter()
void tst_QSplitter::task187373_addAbstractScrollAreas_data()
{
- QTest::addColumn<QString>("className");
+ QTest::addColumn<QByteArray>("className");
QTest::addColumn<bool>("addInConstructor");
QTest::addColumn<bool>("addOutsideConstructor");
- QStringList classNames;
- classNames << QLatin1String("QGraphicsView");
- classNames << QLatin1String("QMdiArea");
- classNames << QLatin1String("QScrollArea");
- classNames << QLatin1String("QTextEdit");
- classNames << QLatin1String("QTreeView");
-
- foreach (QString className, classNames) {
- QTest::newRow(qPrintable(className + QLatin1String(" 1"))) << className << false << true;
- QTest::newRow(qPrintable(className + QLatin1String(" 2"))) << className << true << false;
- QTest::newRow(qPrintable(className + QLatin1String(" 3"))) << className << true << true;
+ QList<QByteArray> classNames{
+ "QGraphicsView",
+ "QMdiArea",
+ "QScrollArea",
+ "QTextEdit",
+ "QTreeView"
+ };
+
+ for (const auto &className : std::as_const(classNames)) {
+ QTest::newRow(qPrintable(className + " 1")) << className << false << true;
+ QTest::newRow(qPrintable(className + " 2")) << className << true << false;
+ QTest::newRow(qPrintable(className + " 3")) << className << true << true;
}
}
static QAbstractScrollArea *task187373_createScrollArea(
- QSplitter *splitter, const QString &className, bool addInConstructor)
+ QSplitter *splitter, const QByteArray &className, bool addInConstructor)
{
- if (className == QLatin1String("QGraphicsView"))
+ if (className == "QGraphicsView")
return new QGraphicsView(addInConstructor ? splitter : 0);
- if (className == QLatin1String("QMdiArea"))
+ if (className == "QMdiArea")
return new QMdiArea(addInConstructor ? splitter : 0);
- if (className == QLatin1String("QScrollArea"))
+ if (className == "QScrollArea")
return new QScrollArea(addInConstructor ? splitter : 0);
- if (className == QLatin1String("QTextEdit"))
+ if (className == "QTextEdit")
return new QTextEdit(addInConstructor ? splitter : 0);
- if (className == QLatin1String("QTreeView"))
+ if (className == "QTreeView")
return new QTreeView(addInConstructor ? splitter : 0);
return 0;
}
void tst_QSplitter::task187373_addAbstractScrollAreas()
{
- QFETCH(QString, className);
+ QFETCH(QByteArray, className);
QFETCH(bool, addInConstructor);
QFETCH(bool, addOutsideConstructor);
QVERIFY(addInConstructor || addOutsideConstructor);
- QSplitter *splitter = new QSplitter;
- splitter->show();
- QVERIFY(splitter->isVisible());
+ QSplitter splitter;
+ splitter.show();
+ QVERIFY(splitter.isVisible());
- QAbstractScrollArea *w = task187373_createScrollArea(splitter, className, addInConstructor);
+ QAbstractScrollArea *w = task187373_createScrollArea(&splitter, className, addInConstructor);
QVERIFY(w);
if (addOutsideConstructor)
- splitter->addWidget(w);
+ splitter.addWidget(w);
QTRY_VERIFY(w->isVisible());
QVERIFY(!w->isHidden());
@@ -1010,7 +1032,7 @@ void tst_QSplitter::taskQTBUG_4101_ensureOneNonCollapsedWidget()
QFETCH(bool, testingHide);
MyFriendlySplitter s;
- QLabel *l;
+ QLabel *l = nullptr;
for (int i = 0; i < 5; ++i) {
l = new QLabel(QString("Label ") + QChar('A' + i));
l->setAlignment(Qt::AlignCenter);
@@ -1026,6 +1048,24 @@ void tst_QSplitter::taskQTBUG_4101_ensureOneNonCollapsedWidget()
QTRY_VERIFY(s.sizes().at(0) > 0);
}
+void tst_QSplitter::taskQTBUG_102249_moveNonPressed()
+{
+ QSplitter s;
+ s.setOpaqueResize(true);
+ s.addWidget(new QWidget());
+ s.addWidget(new QWidget());
+ s.show();
+
+ QSignalSpy spyMove(&s, &QSplitter::splitterMoved);
+ QPointF posOutOfWidget = QPointF(30, 30);
+ QMouseEvent me(QEvent::MouseMove,
+ posOutOfWidget, s.mapToGlobal(posOutOfWidget),
+ Qt::NoButton, Qt::MouseButtons(Qt::LeftButton),
+ Qt::NoModifier);
+ qApp->sendEvent(s.handle(0), &me);
+ QCOMPARE(spyMove.size(), 0);
+}
+
void tst_QSplitter::setLayout()
{
QSplitter splitter;
diff --git a/tests/auto/widgets/widgets/qstackedwidget/CMakeLists.txt b/tests/auto/widgets/widgets/qstackedwidget/CMakeLists.txt
index 7c99df28a4..0c79cf29f4 100644
--- a/tests/auto/widgets/widgets/qstackedwidget/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qstackedwidget/CMakeLists.txt
@@ -1,13 +1,21 @@
-# Generated from qstackedwidget.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qstackedwidget Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qstackedwidget LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qstackedwidget
SOURCES
tst_qstackedwidget.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
+ Qt::WidgetsPrivate
)
diff --git a/tests/auto/widgets/widgets/qstackedwidget/tst_qstackedwidget.cpp b/tests/auto/widgets/widgets/qstackedwidget/tst_qstackedwidget.cpp
index df3b943e05..0a1b140867 100644
--- a/tests/auto/widgets/widgets/qstackedwidget/tst_qstackedwidget.cpp
+++ b/tests/auto/widgets/widgets/qstackedwidget/tst_qstackedwidget.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>
@@ -36,6 +11,8 @@
#include <QHBoxLayout>
#include <qlineedit.h>
+#include <QtWidgets/private/qapplication_p.h>
+
class tst_QStackedWidget : public QObject
{
Q_OBJECT
@@ -182,7 +159,7 @@ void tst_QStackedWidget::dynamicPages()
le11->setFocus(); // set focus to second widget in the page
sw->resize(200, 200);
sw->show();
- qApp->setActiveWindow(sw);
+ QApplicationPrivate::setActiveWindow(sw);
QVERIFY(QTest::qWaitForWindowActive(sw));
QTRY_COMPARE(QApplication::focusWidget(), le11);
diff --git a/tests/auto/widgets/widgets/qstatusbar/CMakeLists.txt b/tests/auto/widgets/widgets/qstatusbar/CMakeLists.txt
index e4e19e230e..3bda170936 100644
--- a/tests/auto/widgets/widgets/qstatusbar/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qstatusbar/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qstatusbar.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qstatusbar Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qstatusbar LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qstatusbar
SOURCES
tst_qstatusbar.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
)
diff --git a/tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp b/tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp
index d7079197ce..b0a53ba01a 100644
--- a/tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp
+++ b/tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.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>
@@ -48,6 +23,7 @@ private slots:
void tempMessage();
void insertWidget();
void insertPermanentWidget();
+ void removeWidget();
void setSizeGripEnabled();
void task194017_hiddenWidget();
void QTBUG4334_hiddenOnMaximizedWindow();
@@ -129,6 +105,49 @@ void tst_QStatusBar::insertPermanentWidget()
QCOMPARE(sb.insertPermanentWidget(1, new QLabel("foo")), 6);
}
+void tst_QStatusBar::removeWidget()
+{
+ QStatusBar sb;
+ std::vector<std::unique_ptr<QLabel>> widgets;
+ std::vector<bool> states;
+ for (int i = 0; i < 10; ++i) {
+ const QString text = i > 5 ? QString("p_%1").arg(i) : QString::number(i);
+ widgets.push_back(std::make_unique<QLabel>(text));
+ states.push_back(true);
+ }
+
+ for (auto &&widget : widgets) {
+ if (widget->text().startsWith("p_"))
+ sb.addPermanentWidget(widget.get());
+ else
+ sb.addWidget(widget.get());
+ }
+ sb.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&sb));
+
+ auto checkStates = [&]{
+ for (size_t index = 0; index < std::size(widgets); ++index) {
+ if (widgets.at(index)->isVisible() != states.at(index)) {
+ qCritical("Mismatch for widget at index %zu\n"
+ "\tActual : %s\n"
+ "\tExpected: %s",
+ index, widgets.at(index)->isVisible() ? "true" : "false",
+ states.at(index) ? "true" : "false");
+ return false;
+ }
+ }
+ return true;
+ };
+
+ QVERIFY(checkStates());
+ // remove every widget except the first to trigger unstable reference
+ for (size_t i = 2; i < std::size(widgets); ++i) {
+ sb.removeWidget(widgets[i].get());
+ states[i] = false;
+ QVERIFY2(checkStates(), qPrintable(QString("Failure at index %1").arg(i)));
+ }
+}
+
void tst_QStatusBar::setSizeGripEnabled()
{
if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
@@ -297,18 +316,18 @@ void tst_QStatusBar::messageChangedSignal()
testWidget->showMessage("Ready", 0);
QCOMPARE(testWidget->currentMessage(), QString("Ready"));
QCOMPARE(testWidget->currentMessage(), currentMessage);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.takeFirst().at(0).toString(), currentMessage);
testWidget->clearMessage();
QCOMPARE(testWidget->currentMessage(), QString());
QCOMPARE(testWidget->currentMessage(), currentMessage);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.takeFirst().at(0).toString(), currentMessage);
testWidget->showMessage("Ready", 0);
testWidget->showMessage("Ready", 0);
QCOMPARE(testWidget->currentMessage(), QString("Ready"));
QCOMPARE(testWidget->currentMessage(), currentMessage);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.takeFirst().at(0).toString(), currentMessage);
}
diff --git a/tests/auto/widgets/widgets/qtabbar/BLACKLIST b/tests/auto/widgets/widgets/qtabbar/BLACKLIST
deleted file mode 100644
index 735b044d8b..0000000000
--- a/tests/auto/widgets/widgets/qtabbar/BLACKLIST
+++ /dev/null
@@ -1,2 +0,0 @@
-[sizeHints]
-redhatenterpriselinuxworkstation-6.6
diff --git a/tests/auto/widgets/widgets/qtabbar/CMakeLists.txt b/tests/auto/widgets/widgets/qtabbar/CMakeLists.txt
index edc90d3138..b79e763819 100644
--- a/tests/auto/widgets/widgets/qtabbar/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qtabbar/CMakeLists.txt
@@ -1,13 +1,21 @@
-# Generated from qtabbar.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qtabbar Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtabbar LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qtabbar
SOURCES
tst_qtabbar.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
+ Qt::WidgetsPrivate
)
diff --git a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp
index 1fe6e7d80e..03131cebe4 100644
--- a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp
+++ b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.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) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
#include <QSignalSpy>
@@ -36,6 +11,12 @@
#include <QStyleOptionTab>
#include <QProxyStyle>
#include <QTimer>
+#include <QScreen>
+#include <QWindow>
+
+#include <QtWidgets/private/qtabbar_p.h>
+
+using namespace Qt::StringLiterals;
class TabBar;
@@ -69,6 +50,7 @@ private slots:
void hideTab_data();
void hideTab();
void hideAllTabs();
+ void checkHiddenTab();
void setElideMode_data();
void setElideMode();
@@ -78,6 +60,7 @@ private slots:
void setUsesScrollButtons();
void removeLastTab();
+ void removeLastVisibleTab();
void closeButton();
@@ -101,10 +84,26 @@ private slots:
void mouseReleaseOutsideTabBar();
void mouseWheel();
+ void kineticWheel_data();
+ void kineticWheel();
+ void highResolutionWheel_data();
+ void highResolutionWheel();
void scrollButtons_data();
void scrollButtons();
+ void currentTabLargeFont();
+
+ void hoverTab_data();
+ void hoverTab();
+
+ void resizeKeepsScroll_data();
+ void resizeKeepsScroll();
+ void changeTabTextKeepsScroll();
+ void settingCurrentTabBeforeShowDoesntScroll();
+ void checkPositionsAfterShapeChange();
+ void checkScrollOffsetAfterTabRemoval();
+
private:
void checkPositions(const TabBar &tabbar, const QList<int> &positions);
};
@@ -220,7 +219,7 @@ void tst_QTabBar::testCurrentChanged()
QCOMPARE(tabBar.currentIndex(), 0);
tabBar.setCurrentIndex(tabToSet);
QCOMPARE(tabBar.currentIndex(), tabToSet);
- QCOMPARE(spy.count(), expectedCount);
+ QCOMPARE(spy.size(), expectedCount);
}
class TabBar : public QTabBar
@@ -229,6 +228,7 @@ public:
using QTabBar::initStyleOption;
using QTabBar::moveTab;
using QTabBar::QTabBar;
+ using QTabBar::tabSizeHint;
};
void tst_QTabBar::insertAtCurrentIndex()
@@ -293,7 +293,7 @@ void tst_QTabBar::removeTab()
tabbar.setCurrentIndex(currentIndex);
QSignalSpy spy(&tabbar, SIGNAL(currentChanged(int)));
tabbar.removeTab(deleteIndex);
- QTEST(int(spy.count()), "spyCount");
+ QTEST(int(spy.size()), "spyCount");
QTEST(tabbar.currentIndex(), "finalIndex");
}
@@ -324,7 +324,7 @@ void tst_QTabBar::hideTab()
tabbar.setCurrentIndex(currentIndex);
QSignalSpy spy(&tabbar, &QTabBar::currentChanged);
tabbar.setTabVisible(hideIndex, false);
- QTEST(int(spy.count()), "spyCount");
+ QTEST(int(spy.size()), "spyCount");
QTEST(tabbar.currentIndex(), "finalIndex");
}
@@ -370,6 +370,25 @@ void tst_QTabBar::hideAllTabs()
QVERIFY(sizeHint.width() < prevSizeHint.width());
}
+void tst_QTabBar::checkHiddenTab()
+{
+ QTabBar tabbar;
+
+ tabbar.addTab("foo");
+ tabbar.addTab("bar");
+ tabbar.addTab("baz");
+ tabbar.setCurrentIndex(0);
+ tabbar.setTabVisible(1, false);
+
+ QKeyEvent keyRight(QKeyEvent::KeyPress, Qt::Key_Right, Qt::NoModifier);
+ QVERIFY(QApplication::sendEvent(&tabbar, &keyRight));
+ QCOMPARE(tabbar.currentIndex(), 2);
+
+ QKeyEvent keyLeft(QKeyEvent::KeyPress, Qt::Key_Left, Qt::NoModifier);
+ QVERIFY(QApplication::sendEvent(&tabbar, &keyLeft));
+ QCOMPARE(tabbar.currentIndex(), 0);
+}
+
void tst_QTabBar::setElideMode_data()
{
QTest::addColumn<int>("tabElideMode");
@@ -468,16 +487,49 @@ void tst_QTabBar::removeLastTab()
QTabBar tabbar;
QSignalSpy spy(&tabbar, SIGNAL(currentChanged(int)));
int index = tabbar.addTab("foo");
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.at(0).at(0).toInt(), index);
spy.clear();
tabbar.removeTab(index);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.at(0).at(0).toInt(), -1);
spy.clear();
}
+void tst_QTabBar::removeLastVisibleTab()
+{
+ QTabBar tabbar;
+ tabbar.setSelectionBehaviorOnRemove(QTabBar::SelectionBehavior::SelectRightTab);
+
+ int invisible = tabbar.addTab("invisible");
+ int visible = tabbar.addTab("visible");
+ tabbar.setCurrentIndex(visible);
+ tabbar.adjustSize();
+
+ tabbar.setTabVisible(invisible, false);
+ {
+ QSignalSpy spy(&tabbar, SIGNAL(currentChanged(int)));
+ tabbar.removeTab(visible);
+ QCOMPARE(spy.size(), 1);
+ QCOMPARE(spy.at(0).at(0).toInt(), -1);
+ QCOMPARE(tabbar.currentIndex(), -1);
+ }
+
+ tabbar.setSelectionBehaviorOnRemove(QTabBar::SelectionBehavior::SelectLeftTab);
+ visible = tabbar.insertTab(0, "visible");
+ ++invisible;
+ QVERIFY(!tabbar.isTabVisible(invisible));
+ tabbar.setCurrentIndex(visible);
+ {
+ QSignalSpy spy(&tabbar, SIGNAL(currentChanged(int)));
+ tabbar.removeTab(visible);
+ QCOMPARE(spy.size(), 1);
+ QCOMPARE(spy.at(0).at(0).toInt(), -1);
+ QCOMPARE(tabbar.currentIndex(), -1);
+ }
+}
+
void tst_QTabBar::closeButton()
{
QTabBar tabbar;
@@ -496,7 +548,7 @@ void tst_QTabBar::closeButton()
QSignalSpy spy(&tabbar, SIGNAL(tabCloseRequested(int)));
button->click();
QCOMPARE(tabbar.count(), 1);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
}
Q_DECLARE_METATYPE(QTabBar::ButtonPosition)
@@ -768,36 +820,38 @@ void tst_QTabBar::tabBarClicked()
QSignalSpy clickSpy(&tabBar, SIGNAL(tabBarClicked(int)));
QSignalSpy doubleClickSpy(&tabBar, SIGNAL(tabBarDoubleClicked(int)));
- QCOMPARE(clickSpy.count(), 0);
- QCOMPARE(doubleClickSpy.count(), 0);
+ QCOMPARE(clickSpy.size(), 0);
+ QCOMPARE(doubleClickSpy.size(), 0);
Qt::MouseButton button = Qt::LeftButton;
while (button <= Qt::MaxMouseButton) {
const QPoint tabPos = tabBar.tabRect(0).center();
QTest::mouseClick(&tabBar, button, {}, tabPos);
- QCOMPARE(clickSpy.count(), 1);
+ QCOMPARE(clickSpy.size(), 1);
QCOMPARE(clickSpy.takeFirst().takeFirst().toInt(), 0);
- QCOMPARE(doubleClickSpy.count(), 0);
+ QCOMPARE(doubleClickSpy.size(), 0);
QTest::mouseDClick(&tabBar, button, {}, tabPos);
- QCOMPARE(clickSpy.count(), 1);
+ QCOMPARE(clickSpy.size(), 1);
QCOMPARE(clickSpy.takeFirst().takeFirst().toInt(), 0);
- QCOMPARE(doubleClickSpy.count(), 1);
+ QCOMPARE(doubleClickSpy.size(), 1);
QCOMPARE(doubleClickSpy.takeFirst().takeFirst().toInt(), 0);
+ QTest::mouseRelease(&tabBar, button, {}, tabPos);
const QPoint barPos(tabBar.tabRect(0).right() + 5, tabBar.tabRect(0).center().y());
QTest::mouseClick(&tabBar, button, {}, barPos);
- QCOMPARE(clickSpy.count(), 1);
+ QCOMPARE(clickSpy.size(), 1);
QCOMPARE(clickSpy.takeFirst().takeFirst().toInt(), -1);
- QCOMPARE(doubleClickSpy.count(), 0);
+ QCOMPARE(doubleClickSpy.size(), 0);
QTest::mouseDClick(&tabBar, button, {}, barPos);
- QCOMPARE(clickSpy.count(), 1);
+ QCOMPARE(clickSpy.size(), 1);
QCOMPARE(clickSpy.takeFirst().takeFirst().toInt(), -1);
- QCOMPARE(doubleClickSpy.count(), 1);
+ QCOMPARE(doubleClickSpy.size(), 1);
QCOMPARE(doubleClickSpy.takeFirst().takeFirst().toInt(), -1);
+ QTest::mouseRelease(&tabBar, button, {}, barPos);
button = Qt::MouseButton(button << 1);
}
@@ -839,9 +893,10 @@ void tst_QTabBar::mouseReleaseOutsideTabBar()
QRect rectToBeRepainted;
bool eventFilter(QObject *, QEvent *event) override
{
- if (event->type() == QEvent::Paint
- && rectToBeRepainted.contains(static_cast<QPaintEvent *>(event)->rect()))
+ if (event->type() == QEvent::Paint &&
+ static_cast<QPaintEvent *>(event)->rect().contains(rectToBeRepainted)) {
repainted = true;
+ }
return false;
}
} repaintChecker;
@@ -856,14 +911,15 @@ void tst_QTabBar::mouseReleaseOutsideTabBar()
QRect tabRect = tabBar.tabRect(1);
QPoint tabCenter = tabRect.center();
+ repaintChecker.rectToBeRepainted = tabRect;
+ // if a press repaints the tab...
QTest::mousePress(&tabBar, Qt::LeftButton, {}, tabCenter);
- QTest::mouseEvent(QTest::MouseMove, &tabBar, Qt::LeftButton, {}, tabCenter + QPoint(tabCenter.x(), tabCenter.y() + tabRect.height()));
+ const bool pressRepainted = QTest::qWaitFor([&]{ return repaintChecker.repainted; }, 250);
- // make sure the holding tab is repainted after releasing the mouse
+ // ... then releasing the mouse outside the tabbar should repaint it as well
repaintChecker.repainted = false;
- repaintChecker.rectToBeRepainted = tabRect;
QTest::mouseRelease(&tabBar, Qt::LeftButton, {}, tabCenter + QPoint(tabCenter.x(), tabCenter.y() + tabRect.height()));
- QTRY_VERIFY(repaintChecker.repainted);
+ QTRY_COMPARE(repaintChecker.repainted, pressRepainted);
}
void tst_QTabBar::checkPositions(const TabBar &tabbar, const QList<int> &positions)
@@ -879,20 +935,25 @@ void tst_QTabBar::checkPositions(const TabBar &tabbar, const QList<int> &positio
}
#if QT_CONFIG(wheelevent)
-// defined to be 120 by the wheel mouse vendors according to the docs
-#define WHEEL_DELTA 120
class TabBarScrollingProxyStyle : public QProxyStyle
{
public:
- TabBarScrollingProxyStyle() : QProxyStyle(), scrolling(true)
+ TabBarScrollingProxyStyle(const QString &defStyle = {})
+ : QProxyStyle(defStyle), scrolling(true)
{ }
int styleHint(StyleHint hint, const QStyleOption *option = 0,
const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const override
{
- if (hint == QStyle::SH_TabBar_AllowWheelScrolling)
+ switch (hint) {
+ case QStyle::SH_TabBar_AllowWheelScrolling:
return scrolling;
+ case SH_TabBar_ElideMode:
+ return Qt::ElideNone;
+ default:
+ break;
+ }
return QProxyStyle::styleHint(hint, option, widget, returnData);
}
@@ -902,37 +963,238 @@ public:
void tst_QTabBar::mouseWheel()
{
+ TabBar tabbar;
- // apply custom style to app, which can toggle tabbar scrolling behavior
- QCoreApplication *applicationInstance = QApplication::instance();
- QVERIFY(applicationInstance != 0);
- auto *proxyStyle = new TabBarScrollingProxyStyle;
- QApplication::setStyle(proxyStyle);
+ // apply custom style to the tabbar, which can toggle tabbar scrolling behavior
+ TabBarScrollingProxyStyle proxyStyle;
+ tabbar.setStyle(&proxyStyle);
// make tabbar with three tabs, select the middle one
- TabBar tabbar;
tabbar.addTab("one");
tabbar.addTab("two");
tabbar.addTab("three");
int startIndex = 1;
tabbar.setCurrentIndex(startIndex);
+ const auto systemId = QPointingDevice::primaryPointingDevice()->systemId() + 1;
+ QPointingDevice clickyWheel("test clicky wheel", systemId, QInputDevice::DeviceType::Mouse,
+ QPointingDevice::PointerType::Generic,
+ QInputDevice::Capability::Position | QInputDevice::Capability::Scroll,
+ 1, 3);
+
// define scroll event
const QPoint wheelPoint = tabbar.rect().bottomRight();
- QWheelEvent event(wheelPoint, tabbar.mapToGlobal(wheelPoint), QPoint(), QPoint(0, WHEEL_DELTA),
- Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false);
+ QWheelEvent event(wheelPoint, tabbar.mapToGlobal(wheelPoint),
+ QPoint(), QPoint(0, QWheelEvent::DefaultDeltasPerStep),
+ Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false,
+ Qt::MouseEventSynthesizedByApplication, &clickyWheel);
// disable scrolling, send scroll event, confirm that tab did not change
- proxyStyle->scrolling = false;
- QVERIFY(applicationInstance->sendEvent(&tabbar, &event));
+ proxyStyle.scrolling = false;
+ QVERIFY(QApplication::sendEvent(&tabbar, &event));
QVERIFY(tabbar.currentIndex() == startIndex);
// enable scrolling, send scroll event, confirm that tab changed
- proxyStyle->scrolling = true;
- QVERIFY(applicationInstance->sendEvent(&tabbar, &event));
+ proxyStyle.scrolling = true;
+ QVERIFY(QApplication::sendEvent(&tabbar, &event));
QVERIFY(tabbar.currentIndex() != startIndex);
}
+void tst_QTabBar::kineticWheel_data()
+{
+ QTest::addColumn<QTabBar::Shape>("tabShape");
+
+ QTest::addRow("North") << QTabBar::RoundedNorth;
+ QTest::addRow("East") << QTabBar::RoundedEast;
+ QTest::addRow("South") << QTabBar::RoundedSouth;
+ QTest::addRow("West") << QTabBar::RoundedWest;
+}
+
+void tst_QTabBar::kineticWheel()
+{
+ const auto systemId = QPointingDevice::primaryPointingDevice()->systemId() + 1;
+ QPointingDevice pixelPad("test pixel pad", systemId, QInputDevice::DeviceType::TouchPad,
+ QPointingDevice::PointerType::Generic,
+ QInputDevice::Capability::Position | QInputDevice::Capability::PixelScroll,
+ 1, 3);
+
+ QFETCH(QTabBar::Shape, tabShape);
+ QWidget window;
+ TabBar tabbar(&window);
+ // Since the macOS style makes sure that all tabs are always visible, we
+ // replace it with the windows style for this test, and use the proxy that
+ // makes sure that scrolling is enabled and that tab texts are not elided.
+ QString defaultStyle;
+ if (QApplication::style()->name() == QStringLiteral("macos"))
+ defaultStyle = "windows";
+ TabBarScrollingProxyStyle proxyStyle(defaultStyle);
+ tabbar.setStyle(&proxyStyle);
+
+ tabbar.addTab("long tab text 1");
+ tabbar.addTab("long tab text 2");
+ tabbar.addTab("long tab text 3");
+
+ // Make sure we don't have enough space for the tabs and need to scroll
+ const int tabbarLength = tabbar.tabRect(0).width() * 2;
+
+ tabbar.setShape(tabShape);
+ const bool horizontal = tabShape == QTabBar::RoundedNorth
+ || tabShape == QTabBar::RoundedSouth;
+ if (horizontal)
+ tabbar.setFixedWidth(tabbarLength);
+ else
+ tabbar.setFixedHeight(tabbarLength);
+
+ // start with the middle tab, QTabBar will scroll to make it visible
+ const int startIndex = 1;
+ tabbar.setCurrentIndex(startIndex);
+
+ window.setMinimumSize(tabbarLength, tabbarLength);
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+
+ const auto *leftButton = tabbar.findChild<QAbstractButton*>(u"ScrollLeftButton"_s);
+ const auto *rightButton = tabbar.findChild<QAbstractButton*>(u"ScrollRightButton"_s);
+ QVERIFY(leftButton && rightButton);
+ QVERIFY(leftButton->isEnabled() && rightButton->isEnabled());
+
+ // Figure out if any of the buttons is laid out to be in front of the tabs.
+ // We can't use setUsesScrollButtons(false), as then several styles will enforce
+ // a minimum size for the tab bar.
+ const bool leftInFront = ((horizontal && leftButton->pos().x() < tabbar.rect().center().x())
+ || (!horizontal && leftButton->pos().y() < tabbar.rect().center().y()));
+ const bool rightInFront = ((horizontal && rightButton->pos().x() < tabbar.rect().center().x())
+ || (!horizontal && rightButton->pos().y() < tabbar.rect().center().y()));
+ QPoint leftEdge;
+ QPoint rightEdge;
+ if (leftInFront && rightInFront) { // both on the left
+ leftEdge = rightButton->geometry().bottomRight();
+ rightEdge = tabbar.rect().bottomRight();
+ } else if (leftInFront && !rightInFront) {
+ leftEdge = leftButton->geometry().bottomRight();
+ rightEdge = rightButton->geometry().topLeft();
+ } else { // both on the right
+ leftEdge = QPoint(0, 0);
+ rightEdge = leftButton->geometry().topLeft();
+ }
+ // avoid border lines
+ leftEdge += QPoint(2, 2);
+ if (horizontal) {
+ rightEdge += QPoint(-2, 2);
+ } else {
+ rightEdge += QPoint(2, -2);
+ }
+
+ QCOMPARE(tabbar.tabAt(leftEdge), 0);
+ QCOMPARE(tabbar.tabAt(rightEdge), 1);
+
+ const QPoint delta = horizontal ? QPoint(10, 0) : QPoint(0, 10);
+ const QPoint wheelPoint = tabbar.rect().center();
+
+ bool accepted = true;
+ Qt::ScrollPhase phase = Qt::ScrollBegin;
+ // scroll all the way to the end
+ while (accepted) {
+ QWheelEvent event(wheelPoint, tabbar.mapToGlobal(wheelPoint), -delta, -delta,
+ Qt::NoButton, Qt::NoModifier, phase, false,
+ Qt::MouseEventSynthesizedByApplication, &pixelPad);
+ if (phase == Qt::ScrollBegin)
+ phase = Qt::ScrollUpdate;
+ QApplication::sendEvent(&tabbar, &event);
+ accepted = event.isAccepted();
+ }
+ QCOMPARE(tabbar.tabAt(leftEdge), 1);
+ QCOMPARE(tabbar.tabAt(rightEdge), 2);
+ QVERIFY(leftButton->isEnabled());
+ QVERIFY(!rightButton->isEnabled());
+ // kinetic wheel events don't change the current index
+ QVERIFY(tabbar.currentIndex() == startIndex);
+
+ // scroll all the way to the beginning
+ accepted = true;
+ while (accepted) {
+ QWheelEvent event(wheelPoint, tabbar.mapToGlobal(wheelPoint), delta, delta,
+ Qt::NoButton, Qt::NoModifier, phase, false,
+ Qt::MouseEventSynthesizedByApplication, &pixelPad);
+ QApplication::sendEvent(&tabbar, &event);
+ accepted = event.isAccepted();
+ }
+
+ QCOMPARE(tabbar.tabAt(leftEdge), 0);
+ QCOMPARE(tabbar.tabAt(rightEdge), 1);
+ QVERIFY(!leftButton->isEnabled());
+ QVERIFY(rightButton->isEnabled());
+ // kinetic wheel events don't change the current index
+ QVERIFY(tabbar.currentIndex() == startIndex);
+
+ // make tabs small so that we have enough space, and verify sure we can't scroll
+ tabbar.setTabText(0, "A");
+ tabbar.setTabText(1, "B");
+ tabbar.setTabText(2, "C");
+ QVERIFY(tabbar.sizeHint().width() <= tabbar.width() && tabbar.sizeHint().height() <= tabbar.height());
+
+ {
+ QWheelEvent event(wheelPoint, tabbar.mapToGlobal(wheelPoint), -delta, -delta,
+ Qt::NoButton, Qt::NoModifier, phase, false,
+ Qt::MouseEventSynthesizedByApplication, &pixelPad);
+ QApplication::sendEvent(&tabbar, &event);
+ QVERIFY(!event.isAccepted());
+ }
+
+ {
+ QWheelEvent event(wheelPoint, tabbar.mapToGlobal(wheelPoint), delta, delta,
+ Qt::NoButton, Qt::NoModifier, phase, false,
+ Qt::MouseEventSynthesizedByApplication, &pixelPad);
+ QApplication::sendEvent(&tabbar, &event);
+ QVERIFY(!event.isAccepted());
+ }
+}
+
+void tst_QTabBar::highResolutionWheel_data()
+{
+ QTest::addColumn<int>("angleDelta");
+ // Smallest angleDelta for a Logitech MX Master 3 with Linux/X11/Libinput
+ QTest::addRow("increment index") << -16;
+ QTest::addRow("decrement index") << 16;
+}
+
+void tst_QTabBar::highResolutionWheel()
+{
+ TabBar tabbar;
+ TabBarScrollingProxyStyle proxyStyle;
+ tabbar.setStyle(&proxyStyle);
+
+ tabbar.addTab("tab1");
+ tabbar.addTab("tab2");
+ QFETCH(int, angleDelta);
+ // Negative values increment, positive values decrement
+ int startIndex = angleDelta < 0 ? 0 : 1;
+ tabbar.setCurrentIndex(startIndex);
+
+ const auto systemId = QPointingDevice::primaryPointingDevice()->systemId() + 1;
+ QPointingDevice hiResWheel(
+ "test high resolution wheel", systemId, QInputDevice::DeviceType::Mouse,
+ QPointingDevice::PointerType::Generic,
+ QInputDevice::Capability::Position | QInputDevice::Capability::Scroll, 1, 3);
+
+ const QPoint wheelPoint = tabbar.rect().bottomRight();
+ QWheelEvent event(wheelPoint, tabbar.mapToGlobal(wheelPoint), QPoint(),
+ QPoint(angleDelta, angleDelta), Qt::NoButton, Qt::NoModifier,
+ Qt::NoScrollPhase, false, Qt::MouseEventSynthesizedByApplication,
+ &hiResWheel);
+
+ proxyStyle.scrolling = true;
+ for (int accumulated = 0; accumulated < QWheelEvent::DefaultDeltasPerStep;
+ accumulated += qAbs(angleDelta)) {
+ // verify that nothing has changed until the threshold has been reached
+ QVERIFY(tabbar.currentIndex() == startIndex);
+ QVERIFY(QApplication::sendEvent(&tabbar, &event));
+ }
+ QVERIFY(tabbar.currentIndex() != startIndex);
+}
+
+#endif // QT_CONFIG(wheelevent)
+
void tst_QTabBar::scrollButtons_data()
{
QTest::addColumn<QTabWidget::TabPosition>("tabPosition");
@@ -970,8 +1232,8 @@ void tst_QTabBar::scrollButtons()
window.show();
QVERIFY(QTest::qWaitForWindowActive(&window));
- auto *leftB = tabWidget.tabBar()->findChild<QAbstractButton*>(u"ScrollLeftButton"_qs);
- auto *rightB = tabWidget.tabBar()->findChild<QAbstractButton*>(u"ScrollRightButton"_qs);
+ auto *leftB = tabWidget.tabBar()->findChild<QAbstractButton*>(u"ScrollLeftButton"_s);
+ auto *rightB = tabWidget.tabBar()->findChild<QAbstractButton*>(u"ScrollRightButton"_s);
QVERIFY(leftB->isVisible());
QVERIFY(!leftB->isEnabled());
@@ -999,7 +1261,340 @@ void tst_QTabBar::scrollButtons()
QVERIFY(!leftB->isEnabled());
}
-#endif // QT_CONFIG(wheelevent)
+void tst_QTabBar::currentTabLargeFont()
+{
+ TabBar tabBar;
+ tabBar.setStyleSheet(R"(
+ QTabBar::tab::selected {
+ font-size: 24pt;
+ }
+ )");
+
+ tabBar.addTab("Tab Item 1");
+ tabBar.addTab("Tab Item 2");
+ tabBar.addTab("Tab Item 3");
+
+ tabBar.setCurrentIndex(0);
+ tabBar.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&tabBar));
+
+ QList<QRect> oldTabRects;
+ oldTabRects << tabBar.tabRect(0) << tabBar.tabRect(1) << tabBar.tabRect(2);
+ tabBar.setCurrentIndex(1);
+ QList<QRect> newTabRects;
+ newTabRects << tabBar.tabRect(0) << tabBar.tabRect(1) << tabBar.tabRect(2);
+ QVERIFY(oldTabRects != newTabRects);
+}
+
+void tst_QTabBar::hoverTab_data()
+{
+ // Move the cursor away from the widget as not to interfere.
+ // skip this test if we can't
+ const QPoint topLeft = QGuiApplication::primaryScreen()->availableGeometry().topLeft();
+ const QPoint cursorPos = topLeft + QPoint(10, 10);
+ QCursor::setPos(cursorPos);
+ if (!QTest::qWaitFor([cursorPos]{ return QCursor::pos() == cursorPos; }, 500))
+ QSKIP("Can't move mouse");
+
+ QTest::addColumn<bool>("documentMode");
+ QTest::addRow("normal mode") << true;
+ QTest::addRow("document mode") << true;
+}
+
+void tst_QTabBar::hoverTab()
+{
+ QFETCH(bool, documentMode);
+ QWidget topLevel;
+ class TabBar : public QTabBar
+ {
+ public:
+ using QTabBar::QTabBar;
+ void initStyleOption(QStyleOptionTab *option, int tabIndex) const override
+ {
+ QTabBar::initStyleOption(option, tabIndex);
+ styleOptions[tabIndex] = *option;
+ }
+ mutable QHash<int, QStyleOptionTab> styleOptions;
+ } tabbar(&topLevel);
+
+ tabbar.setDocumentMode(documentMode);
+ tabbar.addTab("A");
+ tabbar.addTab("B");
+ tabbar.addTab("C");
+ tabbar.addTab("D");
+
+ tabbar.move(0,0);
+ const QSize size = tabbar.sizeHint();
+ const auto center = topLevel.screen()->availableGeometry().center();
+ topLevel.move(center - QPoint{size.width(), size.height()} / 2);
+ topLevel.setMinimumSize(size);
+ tabbar.ensurePolished();
+
+ // some styles set those flags, some don't. If not, use a style sheet
+ if (!(tabbar.testAttribute(Qt::WA_Hover) || tabbar.hasMouseTracking())) {
+ tabbar.setStyleSheet(R"(
+ QTabBar::tab { background: blue; }
+ QTabBar::tab::hover { background: yellow; }
+ QTabBar::tab::selected { background: red; }
+ )");
+ }
+
+ topLevel.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
+ auto *window = topLevel.windowHandle();
+
+ auto pos = tabbar.mapToParent(tabbar.tabRect(0).center());
+ QTest::mouseMove(window, pos);
+ QTRY_VERIFY(tabbar.styleOptions[0].state & QStyle::State_Selected);
+ QTRY_COMPARE(tabbar.styleOptions[1].state & QStyle::State_MouseOver, QStyle::State_None);
+ QTRY_COMPARE(tabbar.styleOptions[2].state & QStyle::State_MouseOver, QStyle::State_None);
+ QTRY_COMPARE(tabbar.styleOptions[3].state & QStyle::State_MouseOver, QStyle::State_None);
+
+ pos = tabbar.mapToParent(tabbar.tabRect(1).center());
+ QTest::mouseMove(window, pos);
+ QTRY_COMPARE(tabbar.styleOptions[1].state & QStyle::State_MouseOver, QStyle::State_MouseOver);
+ QCOMPARE(tabbar.styleOptions[2].state & QStyle::State_MouseOver, QStyle::State_None);
+ QCOMPARE(tabbar.styleOptions[3].state & QStyle::State_MouseOver, QStyle::State_None);
+
+ pos = tabbar.mapToParent(tabbar.tabRect(2).center());
+ QTest::mouseMove(window, pos);
+ QTRY_COMPARE(tabbar.styleOptions[2].state & QStyle::State_MouseOver, QStyle::State_MouseOver);
+ QCOMPARE(tabbar.styleOptions[1].state & QStyle::State_MouseOver, QStyle::State_None);
+ QCOMPARE(tabbar.styleOptions[3].state & QStyle::State_MouseOver, QStyle::State_None);
+
+ // removing tab 2 lays the tabs out so that they stretch across the
+ // tab bar; tab 1 is now where the cursor was. What matters is that a
+ // different tab is now hovered (rather than none).
+ tabbar.removeTab(2);
+ QTRY_COMPARE(tabbar.styleOptions[1].state & QStyle::State_MouseOver, QStyle::State_MouseOver);
+ QCOMPARE(tabbar.styleOptions[2].state & QStyle::State_MouseOver, QStyle::State_None);
+
+ // inserting a tab at index 2 again should paint the new tab hovered
+ tabbar.insertTab(2, "C2");
+ QTRY_COMPARE(tabbar.styleOptions[2].state & QStyle::State_MouseOver, QStyle::State_MouseOver);
+ QCOMPARE(tabbar.styleOptions[1].state & QStyle::State_MouseOver, QStyle::State_None);
+}
+
+
+void tst_QTabBar::resizeKeepsScroll_data()
+{
+ QTest::addColumn<QTabBar::Shape>("tabShape");
+ QTest::addColumn<bool>("expanding");
+
+ QTest::addRow("North, expanding") << QTabBar::RoundedNorth << true;
+ QTest::addRow("East, expanding") << QTabBar::RoundedEast << true;
+ QTest::addRow("South, expanding") << QTabBar::RoundedSouth << true;
+ QTest::addRow("West, expanding") << QTabBar::RoundedWest << true;
+
+ QTest::addRow("North, not expanding") << QTabBar::RoundedNorth << false;
+ QTest::addRow("South, not expanding") << QTabBar::RoundedSouth << false;
+}
+
+void tst_QTabBar::resizeKeepsScroll()
+{
+ QFETCH(QTabBar::Shape, tabShape);
+ QFETCH(const bool, expanding);
+
+ QTabBar tabBar;
+ TabBarScrollingProxyStyle proxyStyle;
+ tabBar.setStyle(&proxyStyle);
+
+ for (int i = 0; i < 10; ++i)
+ tabBar.addTab(u"Tab Number %1"_s.arg(i));
+
+ tabBar.setShape(tabShape);
+ tabBar.setUsesScrollButtons(true);
+ tabBar.setExpanding(expanding);
+
+ // resize to half
+ const QSize fullSize = tabBar.sizeHint();
+ const bool horizontal = fullSize.width() > fullSize.height();
+ if (horizontal)
+ tabBar.resize(fullSize.width() / 2, fullSize.height());
+ else
+ tabBar.resize(fullSize.width(), fullSize.height() / 2);
+
+ tabBar.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&tabBar));
+
+ const auto getScrollOffset = [&]() -> int {
+ return static_cast<QTabBarPrivate *>(QObjectPrivate::get(&tabBar))->scrollOffset;
+ };
+
+ // select a tab outside, this will scroll
+ tabBar.setCurrentIndex(6);
+ // the first tab is now scrolled out
+ const int scrollOffset = getScrollOffset();
+ QCOMPARE_GT(scrollOffset, 0);
+ // the current index is now fully visible, with margin on both sides
+ tabBar.setCurrentIndex(5);
+
+ // make the tab bar a bit larger, by the width of a tab
+ if (horizontal)
+ tabBar.resize(tabBar.width() + tabBar.tabRect(5).width(), tabBar.height());
+ else
+ tabBar.resize(tabBar.width(), tabBar.height() + tabBar.tabRect(5).height());
+
+ // this should not change the scroll
+ QCOMPARE(getScrollOffset(), scrollOffset);
+
+ // make the tab bar large enough to fit everything with extra space
+ tabBar.resize(fullSize + QSize(50, 50));
+
+ // there should be no scroll
+ QCOMPARE(getScrollOffset(), 0);
+
+ for (int i = 0; i < tabBar.count(); ++i) {
+ tabBar.setCurrentIndex(i);
+ QCOMPARE(getScrollOffset(), 0);
+ }
+}
+
+void tst_QTabBar::changeTabTextKeepsScroll()
+{
+ QTabBar tabBar;
+ TabBarScrollingProxyStyle proxyStyle;
+ tabBar.setStyle(&proxyStyle);
+
+ for (int i = 0; i < 6; ++i)
+ tabBar.addTab(u"Tab Number %1"_s.arg(i));
+
+ const QSize fullSize = tabBar.sizeHint();
+ tabBar.resize(fullSize.width() / 2, fullSize.height());
+
+ tabBar.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&tabBar));
+
+ const auto getScrollOffset = [&]() -> int {
+ return static_cast<QTabBarPrivate *>(QObjectPrivate::get(&tabBar))->scrollOffset;
+ };
+
+ tabBar.setCurrentIndex(3);
+ const int scrollOffset = getScrollOffset();
+ tabBar.setTabText(3, "New title");
+ QCOMPARE(getScrollOffset(), scrollOffset);
+}
+
+void tst_QTabBar::settingCurrentTabBeforeShowDoesntScroll()
+{
+ QTabBar tabBar;
+ TabBarScrollingProxyStyle proxyStyle;
+ tabBar.setStyle(&proxyStyle);
+
+ for (int i = 0; i < 6; ++i)
+ tabBar.addTab(u"Tab Number %1"_s.arg(i));
+
+ const auto getScrollOffset = [&]() -> int {
+ return static_cast<QTabBarPrivate *>(QObjectPrivate::get(&tabBar))->scrollOffset;
+ };
+
+ tabBar.setCurrentIndex(5);
+
+ // changing the current index while the tab bar isn't visible shouldn't scroll yet
+ QCOMPARE(getScrollOffset(), 0);
+
+ // now show the tab bar with a size that's too small to fit the current index
+ const QSize fullSize = tabBar.sizeHint();
+ tabBar.resize(fullSize.width() / 2, fullSize.height());
+
+ tabBar.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&tabBar));
+
+ // this should scroll
+ QCOMPARE_GT(getScrollOffset(), 0);
+}
+
+void tst_QTabBar::checkPositionsAfterShapeChange()
+{
+ class TabWidget : public QTabWidget
+ {
+ public:
+ using QTabWidget::QTabWidget;
+ using QTabWidget::setTabBar;
+ };
+
+ class TabBar : public QTabBar
+ {
+ public:
+ using QTabBar::initStyleOption;
+ void resizeEvent(QResizeEvent *e) override
+ {
+ QTabBar::resizeEvent(e);
+ resized = true;
+ }
+ bool resized = false;
+ };
+
+ TabWidget tabWidget;
+ auto *tabBar = new TabBar;
+ tabWidget.setTabBar(tabBar);
+ for (int i = 0; i < 3; ++i)
+ tabWidget.addTab(new QWidget, u"Tab %1"_s.arg(i));
+ tabWidget.setTabPosition(QTabWidget::North);
+ tabWidget.setCurrentIndex(2);
+ tabWidget.resize(300, 300);
+ tabWidget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&tabWidget));
+
+ tabBar->resized = false;
+ tabWidget.setTabPosition(QTabWidget::East);
+ QVERIFY(QTest::qWaitFor([&]() { return tabBar->resized; }));
+ QStyleOptionTab opt;
+ tabBar->initStyleOption(&opt, 2);
+ QVERIFY(opt.rect.top() > 0);
+}
+
+void tst_QTabBar::checkScrollOffsetAfterTabRemoval()
+{
+ QTabWidget tabWidget;
+ QTabBar *tabBar = tabWidget.tabBar();
+ for (int i = 0; i < 10; ++i)
+ tabWidget.addTab(new QWidget, u"Tab %1"_s.arg(i));
+ tabWidget.setTabPosition(QTabWidget::North);
+ tabWidget.resize(300, 300);
+ tabWidget.setCurrentIndex(0);
+ tabWidget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&tabWidget));
+
+ auto *rightButton = tabBar->findChild<QAbstractButton *>(u"ScrollRightButton"_s);
+ auto *leftButton = tabBar->findChild<QAbstractButton *>(u"ScrollLeftButton"_s);
+ QVERIFY(leftButton);
+ QVERIFY(rightButton);
+ QVERIFY(rightButton->isEnabled());
+ QVERIFY(!leftButton->isEnabled());
+ // scroll to the right
+ tabBar->setCurrentIndex(9);
+ QVERIFY(!rightButton->isEnabled());
+ QVERIFY(leftButton->isEnabled());
+ // scroll to the center
+ tabBar->setCurrentIndex(2);
+ QVERIFY(rightButton->isEnabled());
+ QVERIFY(leftButton->isEnabled());
+
+ const auto getScrollOffset = [&]() -> int {
+ return static_cast<QTabBarPrivate *>(QObjectPrivate::get(tabBar))->scrollOffset;
+ };
+ // the scroll offset should not change when a tab right outside
+ // the scroll rect is removed
+ auto oldOffset = getScrollOffset();
+ tabWidget.removeTab(9);
+ QCOMPARE(getScrollOffset(), oldOffset);
+ // the scroll offset must change when a tab left outside
+ // the scroll rect is removed
+ oldOffset = getScrollOffset();
+ tabWidget.removeTab(0);
+ QVERIFY(getScrollOffset() < oldOffset);
+
+ // the scroll offset must change when there is empty
+ // place in the right after tab removal
+ oldOffset = getScrollOffset();
+ QVERIFY(oldOffset > 0);
+ for (int i : { 7, 6, 5, 4, 3 })
+ tabWidget.removeTab(i);
+ QCOMPARE(getScrollOffset(), 0);
+ QVERIFY(!rightButton->isVisible());
+ QVERIFY(!leftButton->isVisible());
+}
QTEST_MAIN(tst_QTabBar)
#include "tst_qtabbar.moc"
diff --git a/tests/auto/widgets/widgets/qtabwidget/CMakeLists.txt b/tests/auto/widgets/widgets/qtabwidget/CMakeLists.txt
index d0689d0b66..a8b48e925c 100644
--- a/tests/auto/widgets/widgets/qtabwidget/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qtabwidget/CMakeLists.txt
@@ -1,15 +1,22 @@
-# Generated from qtabwidget.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qtabwidget Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtabwidget LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qtabwidget
SOURCES
tst_qtabwidget.cpp
INCLUDE_DIRECTORIES
..
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
Qt::WidgetsPrivate
@@ -19,6 +26,6 @@ qt_internal_add_test(tst_qtabwidget
#####################################################################
qt_internal_extend_target(tst_qtabwidget CONDITION WIN32
- PUBLIC_LIBRARIES
+ LIBRARIES
user32
)
diff --git a/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp b/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp
index 0e7012482d..d7bfdfaad2 100644
--- a/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp
+++ b/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.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>
@@ -85,6 +60,7 @@ private slots:
void tabPosition();
void tabEnabled();
void tabHidden();
+ void checkHiddenTab();
void tabText();
void tabShape();
void tabTooltip();
@@ -104,6 +80,9 @@ private slots:
void moveCurrentTab();
void autoHide();
+ void setCurrentBeforeShow_data();
+ void setCurrentBeforeShow();
+
private:
int addPage();
void removePage(int index);
@@ -274,6 +253,32 @@ void tst_QTabWidget::tabHidden()
}
}
+void tst_QTabWidget::checkHiddenTab()
+{
+ tw->addTab(new QWidget(), "foo");
+ tw->addTab(new QWidget(), "bar");
+ tw->addTab(new QWidget(), "baz");
+ QCOMPARE(tw->count(), 3);
+ tw->setCurrentIndex(0);
+ tw->setTabVisible(1, false);
+
+ QKeyEvent keyTab(QKeyEvent::KeyPress, Qt::Key_Tab, Qt::ControlModifier);
+ QVERIFY(QApplication::sendEvent(tw, &keyTab));
+ QCOMPARE(tw->currentIndex(), 2);
+ QVERIFY(QApplication::sendEvent(tw, &keyTab));
+ QCOMPARE(tw->currentIndex(), 0);
+ QVERIFY(QApplication::sendEvent(tw, &keyTab));
+ QCOMPARE(tw->currentIndex(), 2);
+
+ QKeyEvent keyBacktab(QKeyEvent::KeyPress, Qt::Key_Backtab, Qt::ControlModifier);
+ QVERIFY(QApplication::sendEvent(tw, &keyBacktab));
+ QCOMPARE(tw->currentIndex(), 0);
+ QVERIFY(QApplication::sendEvent(tw, &keyBacktab));
+ QCOMPARE(tw->currentIndex(), 2);
+ QVERIFY(QApplication::sendEvent(tw, &keyBacktab));
+ QCOMPARE(tw->currentIndex(), 0);
+}
+
void tst_QTabWidget::tabText()
{
// Test bad arguments
@@ -383,12 +388,12 @@ void tst_QTabWidget::currentIndex()
QCOMPARE(tw->currentIndex(), -1);
tw->setCurrentIndex(-1);
QCOMPARE(tw->currentIndex(), -1);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
int firstIndex = addPage();
tw->setCurrentIndex(firstIndex);
QCOMPARE(tw->currentIndex(), firstIndex);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QList<QVariant> arguments = spy.takeFirst();
QCOMPARE(arguments.at(0).toInt(), firstIndex);
@@ -396,19 +401,19 @@ void tst_QTabWidget::currentIndex()
QCOMPARE(tw->currentIndex(), firstIndex);
tw->setCurrentIndex(index);
QCOMPARE(tw->currentIndex(), index);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
arguments = spy.takeFirst();
QCOMPARE(arguments.at(0).toInt(), index);
removePage(index);
QCOMPARE(tw->currentIndex(), firstIndex);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
arguments = spy.takeFirst();
QCOMPARE(arguments.at(0).toInt(), firstIndex);
removePage(firstIndex);
QCOMPARE(tw->currentIndex(), -1);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
arguments = spy.takeFirst();
QCOMPARE(arguments.at(0).toInt(), -1);
}
@@ -689,8 +694,8 @@ void tst_QTabWidget::tabBarClicked()
QSignalSpy clickSpy(&tabWidget, SIGNAL(tabBarClicked(int)));
QSignalSpy doubleClickSpy(&tabWidget, SIGNAL(tabBarDoubleClicked(int)));
- QCOMPARE(clickSpy.count(), 0);
- QCOMPARE(doubleClickSpy.count(), 0);
+ QCOMPARE(clickSpy.size(), 0);
+ QCOMPARE(doubleClickSpy.size(), 0);
QTabBar &tabBar = *tabWidget.tabBar();
Qt::MouseButton button = Qt::LeftButton;
@@ -698,27 +703,27 @@ void tst_QTabWidget::tabBarClicked()
const QPoint tabPos = tabBar.tabRect(0).center();
QTest::mouseClick(&tabBar, button, {}, tabPos);
- QCOMPARE(clickSpy.count(), 1);
+ QCOMPARE(clickSpy.size(), 1);
QCOMPARE(clickSpy.takeFirst().takeFirst().toInt(), 0);
- QCOMPARE(doubleClickSpy.count(), 0);
+ QCOMPARE(doubleClickSpy.size(), 0);
QTest::mouseDClick(&tabBar, button, {}, tabPos);
- QCOMPARE(clickSpy.count(), 1);
+ QCOMPARE(clickSpy.size(), 1);
QCOMPARE(clickSpy.takeFirst().takeFirst().toInt(), 0);
- QCOMPARE(doubleClickSpy.count(), 1);
+ QCOMPARE(doubleClickSpy.size(), 1);
QCOMPARE(doubleClickSpy.takeFirst().takeFirst().toInt(), 0);
const QPoint barPos(tabBar.tabRect(0).right() + 5, tabBar.tabRect(0).center().y());
QTest::mouseClick(&tabBar, button, {}, barPos);
- QCOMPARE(clickSpy.count(), 1);
+ QCOMPARE(clickSpy.size(), 1);
QCOMPARE(clickSpy.takeFirst().takeFirst().toInt(), -1);
- QCOMPARE(doubleClickSpy.count(), 0);
+ QCOMPARE(doubleClickSpy.size(), 0);
QTest::mouseDClick(&tabBar, button, {}, barPos);
- QCOMPARE(clickSpy.count(), 1);
+ QCOMPARE(clickSpy.size(), 1);
QCOMPARE(clickSpy.takeFirst().takeFirst().toInt(), -1);
- QCOMPARE(doubleClickSpy.count(), 1);
+ QCOMPARE(doubleClickSpy.size(), 1);
QCOMPARE(doubleClickSpy.takeFirst().takeFirst().toInt(), -1);
button = Qt::MouseButton(button << 1);
@@ -775,5 +780,39 @@ void tst_QTabWidget::autoHide()
QVERIFY(heightForWidth1 > tabWidget.heightForWidth(20));
}
+void tst_QTabWidget::setCurrentBeforeShow_data()
+{
+ QTest::addColumn<QTabWidget::TabPosition>("tabPosition");
+ QTest::newRow("West") << QTabWidget::West;
+ QTest::newRow("North") << QTabWidget::North;
+ QTest::newRow("East") << QTabWidget::East;
+ QTest::newRow("South") << QTabWidget::South;
+}
+
+void tst_QTabWidget::setCurrentBeforeShow()
+{
+ QFETCH(QTabWidget::TabPosition, tabPosition);
+
+ QTabWidget tabWidget;
+ tabWidget.setTabPosition(tabPosition);
+
+ QPixmap pm(50, 50);
+ pm.fill(Qt::red);
+ const QIcon icon(pm);
+ for (int i = 0; i < 4; ++i)
+ tabWidget.addTab(new QWidget, icon, QString("Tab %1").arg(i));
+
+ // the tab widget has space for the entire tab bar
+ tabWidget.resize(tabWidget.tabBar()->sizeHint() + QSize(50, 50));
+ tabWidget.setCurrentIndex(2);
+ tabWidget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&tabWidget));
+
+ QCOMPARE_GE(tabWidget.tabBar()->tabRect(0).x(), 0);
+ QCOMPARE_GE(tabWidget.tabBar()->tabRect(0).y(), 0);
+
+ QTest::qWait(2000);
+}
+
QTEST_MAIN(tst_QTabWidget)
#include "tst_qtabwidget.moc"
diff --git a/tests/auto/widgets/widgets/qtextbrowser/CMakeLists.txt b/tests/auto/widgets/widgets/qtextbrowser/CMakeLists.txt
index 170ac1e139..4a80068d75 100644
--- a/tests/auto/widgets/widgets/qtextbrowser/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qtextbrowser/CMakeLists.txt
@@ -1,9 +1,16 @@
-# Generated from qtextbrowser.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qtextbrowser Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtextbrowser LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
file(GLOB_RECURSE test_data_glob
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -22,9 +29,10 @@ list(APPEND test_data ${test_data_glob})
qt_internal_add_test(tst_qtextbrowser
SOURCES
tst_qtextbrowser.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
+ Qt::WidgetsPrivate
TESTDATA ${test_data}
)
diff --git a/tests/auto/widgets/widgets/qtextbrowser/tst_qtextbrowser.cpp b/tests/auto/widgets/widgets/qtextbrowser/tst_qtextbrowser.cpp
index ec187a55b0..5d66f5922a 100644
--- a/tests/auto/widgets/widgets/qtextbrowser/tst_qtextbrowser.cpp
+++ b/tests/auto/widgets/widgets/qtextbrowser/tst_qtextbrowser.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 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) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
@@ -37,12 +12,14 @@
#include <qtextbrowser.h>
#include <qtextobject.h>
+#include <QtWidgets/private/qapplication_p.h>
+
class TestBrowser : public QTextBrowser
{
public:
inline TestBrowser() {
show();
- QApplication::setActiveWindow(this);
+ QApplicationPrivate::setActiveWindow(this);
activateWindow();
setFocus();
QVERIFY(QTest::qWaitForWindowActive(this));
@@ -245,29 +222,29 @@ void tst_QTextBrowser::relativeLinks()
QSignalSpy sourceChangedSpy(browser, SIGNAL(sourceChanged(QUrl)));
browser->setSource(QUrl("subdir/../qtextbrowser.html"));
QVERIFY(!browser->document()->isEmpty());
- QCOMPARE(sourceChangedSpy.count(), 1);
+ QCOMPARE(sourceChangedSpy.size(), 1);
QCOMPARE(sourceChangedSpy.takeFirst()[0].toUrl(), QUrl("subdir/../qtextbrowser.html"));
browser->setSource(QUrl("subdir/index.html"));
QVERIFY(!browser->document()->isEmpty());
- QCOMPARE(sourceChangedSpy.count(), 1);
+ QCOMPARE(sourceChangedSpy.size(), 1);
QCOMPARE(sourceChangedSpy.takeFirst()[0].toUrl(), QUrl("subdir/index.html"));
browser->setSource(QUrl("anchor.html"));
QVERIFY(!browser->document()->isEmpty());
- QCOMPARE(sourceChangedSpy.count(), 1);
+ QCOMPARE(sourceChangedSpy.size(), 1);
QCOMPARE(sourceChangedSpy.takeFirst()[0].toUrl(), QUrl("anchor.html"));
browser->setSource(QUrl("subdir/index.html"));
QVERIFY(!browser->document()->isEmpty());
- QCOMPARE(sourceChangedSpy.count(), 1);
+ QCOMPARE(sourceChangedSpy.size(), 1);
QCOMPARE(sourceChangedSpy.takeFirst()[0].toUrl(), QUrl("subdir/index.html"));
// using QUrl::fromLocalFile()
browser->setSource(QUrl::fromLocalFile("anchor.html"));
QVERIFY(!browser->document()->isEmpty());
- QCOMPARE(sourceChangedSpy.count(), 1);
+ QCOMPARE(sourceChangedSpy.size(), 1);
QCOMPARE(sourceChangedSpy.takeFirst()[0].toUrl(), QUrl("file:anchor.html"));
browser->setSource(QUrl("subdir/../qtextbrowser.html"));
QVERIFY(!browser->document()->isEmpty());
- QCOMPARE(sourceChangedSpy.count(), 1);
+ QCOMPARE(sourceChangedSpy.size(), 1);
QCOMPARE(sourceChangedSpy.takeFirst()[0].toUrl(), QUrl("subdir/../qtextbrowser.html"));
}
@@ -299,9 +276,9 @@ void tst_QTextBrowser::forwardBackwardAvailable()
browser->setSource(QUrl::fromLocalFile("anchor.html"));
QVERIFY(!browser->isBackwardAvailable());
QVERIFY(!browser->isForwardAvailable());
- QCOMPARE(backwardSpy.count(), 1);
+ QCOMPARE(backwardSpy.size(), 1);
QVERIFY(!backwardSpy.at(0).at(0).toBool());
- QCOMPARE(forwardSpy.count(), 1);
+ QCOMPARE(forwardSpy.size(), 1);
QVERIFY(!forwardSpy.at(0).at(0).toBool());
backwardSpy.clear();
@@ -310,9 +287,9 @@ void tst_QTextBrowser::forwardBackwardAvailable()
browser->setSource(QUrl::fromLocalFile("bigpage.html"));
QVERIFY(browser->isBackwardAvailable());
QVERIFY(!browser->isForwardAvailable());
- QCOMPARE(backwardSpy.count(), 1);
+ QCOMPARE(backwardSpy.size(), 1);
QVERIFY(backwardSpy.at(0).at(0).toBool());
- QCOMPARE(forwardSpy.count(), 1);
+ QCOMPARE(forwardSpy.size(), 1);
QVERIFY(!forwardSpy.at(0).at(0).toBool());
backwardSpy.clear();
@@ -321,9 +298,9 @@ void tst_QTextBrowser::forwardBackwardAvailable()
browser->setSource(QUrl::fromLocalFile("pagewithbg.html"));
QVERIFY(browser->isBackwardAvailable());
QVERIFY(!browser->isForwardAvailable());
- QCOMPARE(backwardSpy.count(), 1);
+ QCOMPARE(backwardSpy.size(), 1);
QVERIFY(backwardSpy.at(0).at(0).toBool());
- QCOMPARE(forwardSpy.count(), 1);
+ QCOMPARE(forwardSpy.size(), 1);
QVERIFY(!forwardSpy.at(0).at(0).toBool());
backwardSpy.clear();
@@ -332,9 +309,9 @@ void tst_QTextBrowser::forwardBackwardAvailable()
browser->backward();
QVERIFY(browser->isBackwardAvailable());
QVERIFY(browser->isForwardAvailable());
- QCOMPARE(backwardSpy.count(), 1);
+ QCOMPARE(backwardSpy.size(), 1);
QVERIFY(backwardSpy.at(0).at(0).toBool());
- QCOMPARE(forwardSpy.count(), 1);
+ QCOMPARE(forwardSpy.size(), 1);
QVERIFY(forwardSpy.at(0).at(0).toBool());
backwardSpy.clear();
@@ -343,9 +320,9 @@ void tst_QTextBrowser::forwardBackwardAvailable()
browser->backward();
QVERIFY(!browser->isBackwardAvailable());
QVERIFY(browser->isForwardAvailable());
- QCOMPARE(backwardSpy.count(), 1);
+ QCOMPARE(backwardSpy.size(), 1);
QVERIFY(!backwardSpy.at(0).at(0).toBool());
- QCOMPARE(forwardSpy.count(), 1);
+ QCOMPARE(forwardSpy.size(), 1);
QVERIFY(forwardSpy.at(0).at(0).toBool());
backwardSpy.clear();
@@ -354,9 +331,9 @@ void tst_QTextBrowser::forwardBackwardAvailable()
browser->forward();
QVERIFY(browser->isBackwardAvailable());
QVERIFY(browser->isForwardAvailable());
- QCOMPARE(backwardSpy.count(), 1);
+ QCOMPARE(backwardSpy.size(), 1);
QVERIFY(backwardSpy.at(0).at(0).toBool());
- QCOMPARE(forwardSpy.count(), 1);
+ QCOMPARE(forwardSpy.size(), 1);
QVERIFY(forwardSpy.at(0).at(0).toBool());
backwardSpy.clear();
@@ -365,9 +342,9 @@ void tst_QTextBrowser::forwardBackwardAvailable()
browser->forward();
QVERIFY(browser->isBackwardAvailable());
QVERIFY(!browser->isForwardAvailable());
- QCOMPARE(backwardSpy.count(), 1);
+ QCOMPARE(backwardSpy.size(), 1);
QVERIFY(backwardSpy.at(0).at(0).toBool());
- QCOMPARE(forwardSpy.count(), 1);
+ QCOMPARE(forwardSpy.size(), 1);
QVERIFY(!forwardSpy.at(0).at(0).toBool());
backwardSpy.clear();
@@ -385,9 +362,9 @@ void tst_QTextBrowser::clearHistory()
browser->clearHistory();
QVERIFY(!browser->isBackwardAvailable());
QVERIFY(!browser->isForwardAvailable());
- QCOMPARE(backwardSpy.count(), 1);
+ QCOMPARE(backwardSpy.size(), 1);
QVERIFY(!backwardSpy.at(0).at(0).toBool());
- QCOMPARE(forwardSpy.count(), 1);
+ QCOMPARE(forwardSpy.size(), 1);
QVERIFY(!forwardSpy.at(0).at(0).toBool());
QVERIFY(browser->historyTitle(-1).isEmpty());
QVERIFY(browser->historyTitle(0).isEmpty());
@@ -399,9 +376,9 @@ void tst_QTextBrowser::clearHistory()
browser->setSource(QUrl::fromLocalFile("anchor.html"));
QVERIFY(!browser->isBackwardAvailable());
QVERIFY(!browser->isForwardAvailable());
- QCOMPARE(backwardSpy.count(), 1);
+ QCOMPARE(backwardSpy.size(), 1);
QVERIFY(!backwardSpy.at(0).at(0).toBool());
- QCOMPARE(forwardSpy.count(), 1);
+ QCOMPARE(forwardSpy.size(), 1);
QVERIFY(!forwardSpy.at(0).at(0).toBool());
backwardSpy.clear();
@@ -410,9 +387,9 @@ void tst_QTextBrowser::clearHistory()
browser->setSource(QUrl::fromLocalFile("bigpage.html"));
QVERIFY(browser->isBackwardAvailable());
QVERIFY(!browser->isForwardAvailable());
- QCOMPARE(backwardSpy.count(), 1);
+ QCOMPARE(backwardSpy.size(), 1);
QVERIFY(backwardSpy.at(0).at(0).toBool());
- QCOMPARE(forwardSpy.count(), 1);
+ QCOMPARE(forwardSpy.size(), 1);
QVERIFY(!forwardSpy.at(0).at(0).toBool());
backwardSpy.clear();
@@ -421,9 +398,9 @@ void tst_QTextBrowser::clearHistory()
browser->clearHistory();
QVERIFY(!browser->isBackwardAvailable());
QVERIFY(!browser->isForwardAvailable());
- QCOMPARE(backwardSpy.count(), 1);
+ QCOMPARE(backwardSpy.size(), 1);
QVERIFY(!backwardSpy.at(0).at(0).toBool());
- QCOMPARE(forwardSpy.count(), 1);
+ QCOMPARE(forwardSpy.size(), 1);
QVERIFY(!forwardSpy.at(0).at(0).toBool());
QVERIFY(browser->historyTitle(-1).isEmpty());
QVERIFY(browser->historyTitle(1).isEmpty());
@@ -696,7 +673,7 @@ void tst_QTextBrowser::urlEncoding()
browser->setEditFocus(true);
#endif
QTest::keyClick(browser, Qt::Key_Enter);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QUrl url = spy.at(0).at(0).toUrl();
QCOMPARE(url.toEncoded(), QByteArray("http://www.google.com/q=%22"));
diff --git a/tests/auto/widgets/widgets/qtextedit/CMakeLists.txt b/tests/auto/widgets/widgets/qtextedit/CMakeLists.txt
index e90b59ccb8..e406e088ca 100644
--- a/tests/auto/widgets/widgets/qtextedit/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qtextedit/CMakeLists.txt
@@ -1,16 +1,23 @@
-# Generated from qtextedit.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qtextedit Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtextedit LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
list(APPEND test_data "fullWidthSelection")
qt_internal_add_test(tst_qtextedit
SOURCES
tst_qtextedit.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::Gui
Qt::GuiPrivate
@@ -23,6 +30,6 @@ qt_internal_add_test(tst_qtextedit
#####################################################################
qt_internal_extend_target(tst_qtextedit CONDITION MACOS
- PUBLIC_LIBRARIES
+ LIBRARIES
${FWAppKit}
)
diff --git a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp
index 8d5716c129..0136e5b5de 100644
--- a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp
+++ b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.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>
@@ -58,6 +33,10 @@
#include "../../../shared/platforminputcontext.h"
#include <private/qinputmethod_p.h>
+#include <QtWidgets/private/qapplication_p.h>
+
+Q_LOGGING_CATEGORY(lcTests, "qt.widgets.tests")
+
//Used in copyAvailable
typedef QPair<Qt::Key, Qt::KeyboardModifier> keyPairType;
typedef QList<keyPairType> pairListType;
@@ -137,7 +116,13 @@ private slots:
void moveCursor();
#ifndef QT_NO_CLIPBOARD
void mimeDataReimplementations();
+#ifndef QT_NO_TEXTHTMLPARSER
+ void mimeTypesAvailableFromRichText();
#endif
+#if QT_CONFIG(textmarkdownreader)
+ void mimeTypesAvailableFromMarkdown();
+#endif
+#endif // QT_NO_CLIPBOARD
void ctrlEnterShouldInsertLineSeparator_NOT();
void shiftEnterShouldInsertLineSeparator();
void selectWordsFromStringsContainingSeparators_data();
@@ -173,6 +158,7 @@ private slots:
void setDocumentPreservesPalette();
#endif
void pasteFromQt3RichText();
+ void pasteFromMarkdown();
void noWrapBackgrounds();
void preserveCharFormatAfterUnchangingSetPosition();
void twoSameInputMethodEvents();
@@ -209,10 +195,16 @@ private slots:
void preeditCharFormat_data();
void preeditCharFormat();
+ void nextFormatAfterEnterPressed_data();
+ void nextFormatAfterEnterPressed();
+
+ void dontCrashWithCss();
+
private:
void createSelection();
int blockCount() const;
void compareWidgetAndImage(QTextEdit &widget, const QString &imageFileName);
+ bool isMainFontFixed();
QTextEdit *ed;
qreal rootFrameMargin;
@@ -529,9 +521,9 @@ void tst_QTextEdit::clearShouldClearExtraSelections()
sel.cursor = ed->textCursor();
sel.format.setProperty(QTextFormat::FullWidthSelection, true);
ed->setExtraSelections(QList<QTextEdit::ExtraSelection>() << sel);
- QCOMPARE(ed->extraSelections().count(), 1);
+ QCOMPARE(ed->extraSelections().size(), 1);
ed->clear();
- QCOMPARE(ed->extraSelections().count(), 0);
+ QCOMPARE(ed->extraSelections().size(), 0);
}
void tst_QTextEdit::paragSeparatorOnPlaintextAppend()
@@ -731,7 +723,7 @@ void tst_QTextEdit::cursorPositionChanged()
spy.clear();
QTest::keyClick(ed, Qt::Key_A);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QTextCursor cursor = ed->textCursor();
cursor.movePosition(QTextCursor::Start);
@@ -739,18 +731,18 @@ void tst_QTextEdit::cursorPositionChanged()
cursor.movePosition(QTextCursor::End);
spy.clear();
cursor.insertText("Test");
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
cursor.movePosition(QTextCursor::End);
ed->setTextCursor(cursor);
cursor.movePosition(QTextCursor::Start);
spy.clear();
cursor.insertText("Test");
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
QTest::keyClick(ed, Qt::Key_Left);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
cursor.movePosition(QTextCursor::Start);
ed->setTextCursor(cursor);
@@ -759,14 +751,19 @@ void tst_QTextEdit::cursorPositionChanged()
QTest::mouseDClick(ed->viewport(), Qt::LeftButton, {}, ed->cursorRect().center());
QVERIFY(ed->textCursor().hasSelection());
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
CursorPositionChangedRecorder spy2(ed);
QVERIFY(ed->textCursor().position() > 0);
ed->setPlainText("Hello World");
- QCOMPARE(spy2.cursorPositions.count(), 1);
+ QCOMPARE(spy2.cursorPositions.size(), 1);
QCOMPARE(spy2.cursorPositions.at(0), 0);
QCOMPARE(ed->textCursor().position(), 0);
+
+ ed->selectAll();
+ QCOMPARE(spy2.cursorPositions.size(), 2);
+ QCOMPARE(spy2.cursorPositions.at(1), 11);
+ QCOMPARE(ed->textCursor().position(), 11);
}
void tst_QTextEdit::setTextCursor()
@@ -781,7 +778,7 @@ void tst_QTextEdit::setTextCursor()
spy.clear();
ed->setTextCursor(cursor);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
}
#ifndef QT_NO_CLIPBOARD
@@ -798,7 +795,7 @@ void tst_QTextEdit::undoAvailableAfterPaste()
const QString txt("Test");
QApplication::clipboard()->setText(txt);
ed->paste();
- QVERIFY(spy.count() >= 1);
+ QVERIFY(spy.size() >= 1);
QCOMPARE(ed->toPlainText(), txt);
}
#endif
@@ -1051,7 +1048,7 @@ void tst_QTextEdit::noPropertiesOnDefaultTextEditCharFormat()
// on a text edit. Font properties instead should be taken from the
// widget's font (in sync with defaultFont property in document) and the
// foreground color should be taken from the palette.
- QCOMPARE(ed->currentCharFormat().properties().count(), 0);
+ QCOMPARE(ed->currentCharFormat().properties().size(), 0);
}
void tst_QTextEdit::setPlainTextShouldUseCurrentCharFormat()
@@ -1073,9 +1070,9 @@ void tst_QTextEdit::setPlainTextShouldEmitTextChangedOnce()
{
QSignalSpy spy(ed, SIGNAL(textChanged()));
ed->setPlainText("Yankee Doodle");
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
ed->setPlainText("");
- QCOMPARE(spy.count(), 2);
+ QCOMPARE(spy.size(), 2);
}
void tst_QTextEdit::overwriteMode()
@@ -1357,7 +1354,7 @@ void tst_QTextEdit::copyAvailable_data()
//Tests the copyAvailable slot for several cases
void tst_QTextEdit::copyAvailable()
{
- QFETCH(pairListType,keystrokes);
+ QFETCH(const pairListType, keystrokes);
QFETCH(QList<bool>, copyAvailable);
QFETCH(QString, function);
@@ -1370,9 +1367,8 @@ void tst_QTextEdit::copyAvailable()
QSignalSpy spyCopyAvailabe(ed, SIGNAL(copyAvailable(bool)));
//Execute Keystrokes
- foreach(keyPairType keyPair, keystrokes) {
+ for (keyPairType keyPair : keystrokes)
QTest::keyClick(ed, keyPair.first, keyPair.second );
- }
//Execute ed->"function"
if (function == "cut")
@@ -1389,8 +1385,8 @@ void tst_QTextEdit::copyAvailable()
//Compare spied signals
QEXPECT_FAIL("Case7 T,A,A, <- + shift, <- + shift, <- + shift, ctrl + x, undo() | signals: true, false, true",
"Wrong undo selection behaviour. Should be fixed in some future release. (See task: 132482)", Abort);
- QCOMPARE(spyCopyAvailabe.count(), copyAvailable.count());
- for (int i=0;i<spyCopyAvailabe.count(); i++) {
+ QCOMPARE(spyCopyAvailabe.size(), copyAvailable.size());
+ for (int i=0;i<spyCopyAvailabe.size(); i++) {
QVariant variantSpyCopyAvailable = spyCopyAvailabe.at(i).at(0);
QVERIFY2(variantSpyCopyAvailable.toBool() == copyAvailable.at(i), QString("Spied singnal: %1").arg(i).toLatin1());
}
@@ -1426,10 +1422,10 @@ void tst_QTextEdit::moveCursor()
QCOMPARE(ed->textCursor().position(), 0);
ed->moveCursor(QTextCursor::NextCharacter);
QCOMPARE(ed->textCursor().position(), 1);
- QCOMPARE(cursorMovedSpy.count(), 1);
+ QCOMPARE(cursorMovedSpy.size(), 1);
ed->moveCursor(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
QCOMPARE(ed->textCursor().position(), 2);
- QCOMPARE(cursorMovedSpy.count(), 2);
+ QCOMPARE(cursorMovedSpy.size(), 2);
QCOMPARE(ed->textCursor().selectedText(), QString("e"));
}
@@ -1500,7 +1496,63 @@ void tst_QTextEdit::mimeDataReimplementations()
QCOMPARE(ed.insertCallCount, 1);
#endif
}
+
+#ifndef QT_NO_TEXTHTMLPARSER
+void tst_QTextEdit::mimeTypesAvailableFromRichText()
+{
+ MyTextEdit ed;
+ ed.setHtml("<i>Hello <b>World</b></i>");
+ ed.selectAll();
+ ed.copy();
+ const auto *mimeData = QApplication::clipboard()->mimeData();
+ qCDebug(lcTests) << "available mime types" << mimeData->formats();
+ QVERIFY(mimeData->formats().contains("text/plain"));
+#if QT_CONFIG(textmarkdownwriter)
+ QVERIFY(mimeData->formats().contains("text/markdown"));
+ const QByteArray expectedMarkdown = "*Hello **World***\n\n";
+ if (mimeData->data("text/markdown") != expectedMarkdown && isMainFontFixed())
+ QEXPECT_FAIL("", "fixed-pitch main font (QTBUG-103484)", Continue);
+ QCOMPARE(mimeData->data("text/markdown"), expectedMarkdown);
#endif
+#ifndef QT_NO_TEXTHTMLPARSER
+ QVERIFY(mimeData->formats().contains("text/html"));
+ QVERIFY(mimeData->hasHtml());
+#endif
+#ifndef QT_NO_TEXTODFWRITER
+ QVERIFY(mimeData->formats().contains("application/vnd.oasis.opendocument.text"));
+#endif
+}
+#endif // QT_NO_TEXTHTMLPARSER
+
+#if QT_CONFIG(textmarkdownreader)
+void tst_QTextEdit::mimeTypesAvailableFromMarkdown()
+{
+ MyTextEdit ed;
+ const QString md("# TODO\n\n- [x] Fix bugs\n- [ ] Have a beer\n");
+ ed.setMarkdown(md);
+ ed.selectAll();
+ ed.copy();
+ const auto *mimeData = QApplication::clipboard()->mimeData();
+ qCDebug(lcTests) << "available mime types" << mimeData->formats();
+ QVERIFY(mimeData->formats().contains("text/plain"));
+#if QT_CONFIG(textmarkdownwriter)
+ QVERIFY(mimeData->formats().contains("text/markdown"));
+ if (mimeData->data("text/markdown") != md && isMainFontFixed())
+ QEXPECT_FAIL("", "fixed-pitch main font (QTBUG-103484)", Continue);
+ QCOMPARE(mimeData->data("text/markdown"), md);
+#endif
+#ifndef QT_NO_TEXTHTMLPARSER
+ QVERIFY(mimeData->formats().contains("text/html"));
+ QVERIFY(mimeData->hasHtml());
+ QVERIFY(mimeData->html().contains("checked")); // <li class=\"checked\" ...
+#endif
+#ifndef QT_NO_TEXTODFWRITER
+ QVERIFY(mimeData->formats().contains("application/vnd.oasis.opendocument.text"));
+#endif
+}
+#endif // textmarkdownreader
+
+#endif // QT_NO_CLIPBOARD
void tst_QTextEdit::ctrlEnterShouldInsertLineSeparator_NOT()
{
@@ -1648,7 +1700,7 @@ void tst_QTextEdit::ensureVisibleWithRtl()
ed->setLayoutDirection(Qt::RightToLeft);
ed->setLineWrapMode(QTextEdit::NoWrap);
QString txt(500, QChar(QLatin1Char('a')));
- QCOMPARE(txt.length(), 500);
+ QCOMPARE(txt.size(), 500);
ed->setPlainText(txt);
ed->resize(100, 100);
ed->show();
@@ -1699,7 +1751,7 @@ void tst_QTextEdit::extraSelections()
ed->setExtraSelections(QList<QTextEdit::ExtraSelection>() << sel);
QList<QTextEdit::ExtraSelection> selections = ed->extraSelections();
- QCOMPARE(selections.count(), 1);
+ QCOMPARE(selections.size(), 1);
QCOMPARE(selections.at(0).cursor.position(), endPos);
QCOMPARE(selections.at(0).cursor.anchor(), wordPos);
}
@@ -1841,27 +1893,27 @@ void tst_QTextEdit::selectionChanged()
QTest::keyClick(ed, Qt::Key_Right);
QCOMPARE(ed->textCursor().position(), 1);
- QCOMPARE(selectionChangedSpy.count(), 0);
+ QCOMPARE(selectionChangedSpy.size(), 0);
QTest::keyClick(ed, Qt::Key_Right, Qt::ShiftModifier);
QCOMPARE(ed->textCursor().position(), 2);
- QCOMPARE(selectionChangedSpy.count(), 1);
+ QCOMPARE(selectionChangedSpy.size(), 1);
QTest::keyClick(ed, Qt::Key_Right, Qt::ShiftModifier);
QCOMPARE(ed->textCursor().position(), 3);
- QCOMPARE(selectionChangedSpy.count(), 2);
+ QCOMPARE(selectionChangedSpy.size(), 2);
QTest::keyClick(ed, Qt::Key_Right, Qt::ShiftModifier);
QCOMPARE(ed->textCursor().position(), 4);
- QCOMPARE(selectionChangedSpy.count(), 3);
+ QCOMPARE(selectionChangedSpy.size(), 3);
QTest::keyClick(ed, Qt::Key_Right);
QCOMPARE(ed->textCursor().position(), 4);
- QCOMPARE(selectionChangedSpy.count(), 4);
+ QCOMPARE(selectionChangedSpy.size(), 4);
QTest::keyClick(ed, Qt::Key_Right);
QCOMPARE(ed->textCursor().position(), 5);
- QCOMPARE(selectionChangedSpy.count(), 4);
+ QCOMPARE(selectionChangedSpy.size(), 4);
}
#ifndef QT_NO_CLIPBOARD
@@ -2153,6 +2205,18 @@ void tst_QTextEdit::compareWidgetAndImage(QTextEdit &widget, const QString &imag
}
}
+bool tst_QTextEdit::isMainFontFixed()
+{
+ bool ret = QFontInfo(QGuiApplication::font()).fixedPitch();
+ if (ret) {
+ qCWarning(lcTests) << "QFontDatabase::GeneralFont is monospaced: markdown writing is likely to use too many backticks";
+ qCWarning(lcTests) << "system fonts: fixed" << QFontDatabase::systemFont(QFontDatabase::FixedFont)
+ << "fixed?" << QFontInfo(QFontDatabase::systemFont(QFontDatabase::FixedFont)).fixedPitch()
+ << "general" << QFontDatabase::systemFont(QFontDatabase::GeneralFont);
+ }
+ return ret;
+}
+
void tst_QTextEdit::cursorRect()
{
ed->show();
@@ -2173,9 +2237,8 @@ void tst_QTextEdit::setDocumentPreservesPalette()
QWidgetTextControl *control = ed->findChild<QWidgetTextControl *>();
QVERIFY(control);
- QPalette defaultPal = ed->palette();
QPalette whitePal = ed->palette();
- whitePal.setColor(QPalette::Active, QPalette::Text, "white");
+ whitePal.setColor(QPalette::Active, QPalette::Text, Qt::white);
QVERIFY(whitePal != ed->palette());
@@ -2220,6 +2283,24 @@ void tst_QTextEdit::pasteFromQt3RichText()
QCOMPARE(ed->toPlainText(), QString::fromLatin1(" QTextEdit is an "));
}
+void tst_QTextEdit::pasteFromMarkdown()
+{
+ QByteArray richtext("*This* text is **rich**");
+
+ QMimeData mimeData;
+ mimeData.setData("text/markdown", richtext);
+
+ static_cast<PublicTextEdit *>(ed)->publicInsertFromMimeData(&mimeData);
+
+ QCOMPARE(ed->toPlainText(), "This text is rich");
+#if QT_CONFIG(textmarkdownwriter)
+ const auto expectedMarkdown = QString::fromLatin1(richtext + "\n\n");
+ if (ed->toMarkdown() != expectedMarkdown && isMainFontFixed())
+ QEXPECT_FAIL("", "fixed-pitch main font (QTBUG-103484)", Continue);
+ QCOMPARE(ed->toMarkdown(), expectedMarkdown);
+#endif
+}
+
void tst_QTextEdit::noWrapBackgrounds()
{
QWidget topLevel;
@@ -2292,7 +2373,8 @@ void tst_QTextEdit::taskQTBUG_7902_contextMenuCrash()
w->connect(&ti, SIGNAL(timeout()), w, SLOT(deleteLater()));
ti.start(200);
- QContextMenuEvent *cme = new QContextMenuEvent(QContextMenuEvent::Mouse, w->rect().center());
+ QContextMenuEvent *cme = new QContextMenuEvent(QContextMenuEvent::Mouse, w->rect().center(),
+ w->viewport()->mapToGlobal(w->rect().center()));
qApp->postEvent(w->viewport(), cme);
QTest::qWait(300);
@@ -2458,12 +2540,12 @@ void tst_QTextEdit::inputMethodEvent()
QInputMethodEvent event;
event.setCommitString("text");
QApplication::sendEvent(ed, &event);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(ed->toPlainText(), QString("text"));
// test that input method gets chance to commit preedit when removing focus
ed->setText("");
- QApplication::setActiveWindow(ed);
+ QApplicationPrivate::setActiveWindow(ed);
QTRY_VERIFY(QApplication::focusWindow());
QCOMPARE(qApp->focusObject(), ed);
@@ -2488,7 +2570,7 @@ void tst_QTextEdit::inputMethodSelection()
cursor.setPosition(5, QTextCursor::KeepAnchor);
ed->setTextCursor(cursor);
- QCOMPARE(selectionSpy.count(), 1);
+ QCOMPARE(selectionSpy.size(), 1);
QCOMPARE(ed->textCursor().selectionStart(), 0);
QCOMPARE(ed->textCursor().selectionEnd(), 5);
@@ -2497,7 +2579,7 @@ void tst_QTextEdit::inputMethodSelection()
QInputMethodEvent event("", attributes);
QApplication::sendEvent(ed, &event);
- QCOMPARE(selectionSpy.count(), 2);
+ QCOMPARE(selectionSpy.size(), 2);
QCOMPARE(ed->textCursor().selectionStart(), 12);
QCOMPARE(ed->textCursor().selectionEnd(), 17);
}
@@ -2512,7 +2594,7 @@ void tst_QTextEdit::inputMethodQuery()
QGuiApplication::sendEvent(ed, &event);
int anchor = event.value(Qt::ImAnchorPosition).toInt();
int position = event.value(Qt::ImCursorPosition).toInt();
- QCOMPARE(qAbs(position - anchor), text.length());
+ QCOMPARE(qAbs(position - anchor), text.size());
QCOMPARE(event.value(Qt::ImEnabled).toBool(), true);
ed->setEnabled(false);
@@ -2597,7 +2679,7 @@ void tst_QTextEdit::countTextChangedOnRemove()
QKeyEvent event(QEvent::KeyPress, Qt::Key_Backspace, Qt::NoModifier);
QCoreApplication::instance()->notify(&edit, &event);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
}
#if QT_CONFIG(regularexpression)
@@ -2895,5 +2977,103 @@ void tst_QTextEdit::preeditCharFormat()
delete w;
}
+void tst_QTextEdit::nextFormatAfterEnterPressed_data()
+{
+ typedef QMap<int, QVariant> pmap;
+ QTest::addColumn<QString>("html");
+ QTest::addColumn<int>("enterKeyCount");
+ QTest::addColumn<pmap>("expectedPrevBlockProps");
+ QTest::addColumn<pmap>("expectedPrevCharProps");
+ QTest::addColumn<pmap>("expectedNewBlockProps");
+ QTest::addColumn<pmap>("expectedNewCharProps");
+
+ // the BlockBottomMargin on "two" will be removed: property() returns invalid QVariant
+ QTest::newRow("bottom margin after ordered list") << "<ol><li>one</li><li>two</li></ol>" << 1
+ << pmap{{QTextFormat::BlockBottomMargin, {}}} << pmap{}
+ << pmap{{QTextFormat::BlockBottomMargin, 12}} << pmap{};
+ QTest::newRow("double enter after list: default format") << "<ol><li>one</li><li>two</li></ol>" << 2
+ << pmap{{QTextFormat::BlockBottomMargin, {}}} << pmap{}
+ << pmap{} << pmap{};
+ QTest::newRow("continue block quote") << "<blockquote>I'll be back</blockquote>" << 1
+ << pmap{{QTextFormat::BlockLeftMargin, 40}} << pmap{}
+ << pmap{{QTextFormat::BlockLeftMargin, 40}} << pmap{};
+ QTest::newRow("double enter after block quote") << "<blockquote>I'll be back</blockquote>" << 2
+ << pmap{{QTextFormat::BlockLeftMargin, 40}} << pmap{}
+ << pmap{{QTextFormat::BlockLeftMargin, {}}} << pmap{};
+ QTest::newRow("bottom margin after bullet list") << "<ul><li>one</li><li>two</li></ul>" << 1
+ << pmap{{QTextFormat::BlockBottomMargin, {}}} << pmap{}
+ << pmap{{QTextFormat::BlockBottomMargin, 12}} << pmap{};
+ QTest::newRow("paragraph after heading") << "<h1>so big!</h1>" << 1
+ << pmap{{QTextFormat::HeadingLevel, 1}} << pmap{}
+ << pmap{{QTextFormat::HeadingLevel, {}}} << pmap{};
+ QTest::newRow("paragraph after hrule") << "<p style='font-size:18px;'>blah blah<hr/></p>" << 1
+ << pmap{} << pmap{}
+ << pmap{{QTextFormat::BlockTrailingHorizontalRulerWidth, {}}} << pmap{};
+}
+
+void tst_QTextEdit::nextFormatAfterEnterPressed()
+{
+ typedef QMap<int, QVariant> pmap;
+ QFETCH(QString, html);
+ QFETCH(int, enterKeyCount);
+ QFETCH(pmap, expectedPrevBlockProps);
+ QFETCH(pmap, expectedPrevCharProps);
+ QFETCH(pmap, expectedNewBlockProps);
+ QFETCH(pmap, expectedNewCharProps);
+
+ ed->setHtml(html);
+ QTextCursor cursor = ed->textCursor();
+ cursor.movePosition(QTextCursor::End);
+ ed->setTextCursor(cursor);
+
+ if (lcTests().isDebugEnabled()) {
+ ed->show();
+ QTest::qWait(500);
+ }
+
+ for (int i = 0; i < enterKeyCount; ++i)
+ QTest::keyClick(ed, Qt::Key_Enter);
+ QTest::keyClicks(ed, "foo");
+
+ if (lcTests().isDebugEnabled()) {
+ // visually see what happened when debug is enabled
+ QTest::qWait(500);
+ qCDebug(lcTests) << "new block" << Qt::hex << ed->textCursor().blockFormat().properties();
+ qCDebug(lcTests) << "new char" << Qt::hex << ed->textCursor().charFormat().properties();
+ }
+
+ // if expectedNewBlockProps is empty, we expect the current block format to be the default format
+ if (expectedNewBlockProps.isEmpty())
+ QCOMPARE(ed->textCursor().blockFormat(), QTextBlockFormat());
+ // otherwise we expect to find certain property values in the current block format
+ else for (auto it = expectedNewBlockProps.constBegin(); it != expectedNewBlockProps.constEnd(); ++it)
+ QCOMPARE(ed->textCursor().blockFormat().property(it.key()), it.value());
+
+ // if expectedNewCharProps is empty, we expect the current char format to be the default format
+ if (expectedNewCharProps.isEmpty())
+ QCOMPARE(ed->textCursor().charFormat(), QTextCharFormat());
+ // otherwise we expect to find certain property values in the current char format
+ else for (auto it = expectedNewCharProps.constBegin(); it != expectedNewCharProps.constEnd(); ++it)
+ QCOMPARE(ed->textCursor().charFormat().property(it.key()), it.value());
+
+ // check the cases where QWidgetTextControlPrivate::insertParagraphSeparator() should modify
+ // the previous block's block format and/or char format
+ auto prevBlockCursor = ed->textCursor();
+ prevBlockCursor.movePosition(QTextCursor::PreviousBlock);
+ for (auto it = expectedPrevBlockProps.constBegin(); it != expectedPrevBlockProps.constEnd(); ++it)
+ QCOMPARE(prevBlockCursor.blockFormat().property(it.key()), it.value());
+ for (auto it = expectedPrevCharProps.constBegin(); it != expectedPrevCharProps.constEnd(); ++it)
+ QCOMPARE(prevBlockCursor.charFormat().property(it.key()), it.value());
+}
+
+void tst_QTextEdit::dontCrashWithCss()
+{
+ qApp->setStyleSheet("QWidget { font: 10pt; }");
+ QTextEdit edit;
+ edit.show();
+ qApp->setStyleSheet(QString());
+}
+
+
QTEST_MAIN(tst_QTextEdit)
#include "tst_qtextedit.moc"
diff --git a/tests/auto/widgets/widgets/qtoolbar/CMakeLists.txt b/tests/auto/widgets/widgets/qtoolbar/CMakeLists.txt
index 79b4816d53..e9fb01c3e8 100644
--- a/tests/auto/widgets/widgets/qtoolbar/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qtoolbar/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qtoolbar.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qtoolbar Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtoolbar LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qtoolbar
SOURCES
tst_qtoolbar.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::GuiPrivate
Qt::Widgets
diff --git a/tests/auto/widgets/widgets/qtoolbar/tst_qtoolbar.cpp b/tests/auto/widgets/widgets/qtoolbar/tst_qtoolbar.cpp
index 8fea0dcd67..6336b792ed 100644
--- a/tests/auto/widgets/widgets/qtoolbar/tst_qtoolbar.cpp
+++ b/tests/auto/widgets/widgets/qtoolbar/tst_qtoolbar.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>
@@ -47,6 +22,8 @@
#include <qlabel.h>
#include <private/qtoolbarextension_p.h>
+#include <QtWidgets/private/qapplication_p.h>
+
QT_FORWARD_DECLARE_CLASS(QAction)
class tst_QToolBar : public QObject
@@ -162,12 +139,12 @@ void tst_QToolBar::allowedAreas()
QVERIFY(!tb.isAreaAllowed(Qt::RightToolBarArea));
QVERIFY(!tb.isAreaAllowed(Qt::TopToolBarArea));
QVERIFY(!tb.isAreaAllowed(Qt::BottomToolBarArea));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const Qt::ToolBarAreas *>(spy.at(0).value(0).constData()),
tb.allowedAreas());
spy.clear();
tb.setAllowedAreas(tb.allowedAreas());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
tb.setAllowedAreas(Qt::RightToolBarArea);
QCOMPARE((int)tb.allowedAreas(), (int)Qt::RightToolBarArea);
@@ -175,12 +152,12 @@ void tst_QToolBar::allowedAreas()
QVERIFY(tb.isAreaAllowed(Qt::RightToolBarArea));
QVERIFY(!tb.isAreaAllowed(Qt::TopToolBarArea));
QVERIFY(!tb.isAreaAllowed(Qt::BottomToolBarArea));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const Qt::ToolBarAreas *>(spy.at(0).value(0).constData()),
tb.allowedAreas());
spy.clear();
tb.setAllowedAreas(tb.allowedAreas());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
tb.setAllowedAreas(Qt::TopToolBarArea);
QCOMPARE((int)tb.allowedAreas(), (int)Qt::TopToolBarArea);
@@ -188,12 +165,12 @@ void tst_QToolBar::allowedAreas()
QVERIFY(!tb.isAreaAllowed(Qt::RightToolBarArea));
QVERIFY(tb.isAreaAllowed(Qt::TopToolBarArea));
QVERIFY(!tb.isAreaAllowed(Qt::BottomToolBarArea));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const Qt::ToolBarAreas *>(spy.at(0).value(0).constData()),
tb.allowedAreas());
spy.clear();
tb.setAllowedAreas(tb.allowedAreas());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
tb.setAllowedAreas(Qt::BottomToolBarArea);
QCOMPARE((int)tb.allowedAreas(), (int)Qt::BottomToolBarArea);
@@ -201,12 +178,12 @@ void tst_QToolBar::allowedAreas()
QVERIFY(!tb.isAreaAllowed(Qt::RightToolBarArea));
QVERIFY(!tb.isAreaAllowed(Qt::TopToolBarArea));
QVERIFY(tb.isAreaAllowed(Qt::BottomToolBarArea));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const Qt::ToolBarAreas *>(spy.at(0).value(0).constData()),
tb.allowedAreas());
spy.clear();
tb.setAllowedAreas(tb.allowedAreas());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
// multiple dock window areas
tb.setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea);
@@ -215,12 +192,12 @@ void tst_QToolBar::allowedAreas()
QVERIFY(!tb.isAreaAllowed(Qt::RightToolBarArea));
QVERIFY(tb.isAreaAllowed(Qt::TopToolBarArea));
QVERIFY(tb.isAreaAllowed(Qt::BottomToolBarArea));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const Qt::ToolBarAreas *>(spy.at(0).value(0).constData()),
tb.allowedAreas());
spy.clear();
tb.setAllowedAreas(tb.allowedAreas());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
tb.setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);
QCOMPARE(tb.allowedAreas(), Qt::LeftToolBarArea | Qt::RightToolBarArea);
@@ -228,12 +205,12 @@ void tst_QToolBar::allowedAreas()
QVERIFY(tb.isAreaAllowed(Qt::RightToolBarArea));
QVERIFY(!tb.isAreaAllowed(Qt::TopToolBarArea));
QVERIFY(!tb.isAreaAllowed(Qt::BottomToolBarArea));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const Qt::ToolBarAreas *>(spy.at(0).value(0).constData()),
tb.allowedAreas());
spy.clear();
tb.setAllowedAreas(tb.allowedAreas());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
tb.setAllowedAreas(Qt::TopToolBarArea | Qt::LeftToolBarArea);
QCOMPARE(tb.allowedAreas(), Qt::TopToolBarArea | Qt::LeftToolBarArea);
@@ -241,12 +218,12 @@ void tst_QToolBar::allowedAreas()
QVERIFY(!tb.isAreaAllowed(Qt::RightToolBarArea));
QVERIFY(tb.isAreaAllowed(Qt::TopToolBarArea));
QVERIFY(!tb.isAreaAllowed(Qt::BottomToolBarArea));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const Qt::ToolBarAreas *>(spy.at(0).value(0).constData()),
tb.allowedAreas());
spy.clear();
tb.setAllowedAreas(tb.allowedAreas());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
tb.setAllowedAreas(Qt::BottomToolBarArea | Qt::RightToolBarArea);
QCOMPARE(tb.allowedAreas(), Qt::BottomToolBarArea | Qt::RightToolBarArea);
@@ -254,12 +231,12 @@ void tst_QToolBar::allowedAreas()
QVERIFY(tb.isAreaAllowed(Qt::RightToolBarArea));
QVERIFY(!tb.isAreaAllowed(Qt::TopToolBarArea));
QVERIFY(tb.isAreaAllowed(Qt::BottomToolBarArea));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const Qt::ToolBarAreas *>(spy.at(0).value(0).constData()),
tb.allowedAreas());
spy.clear();
tb.setAllowedAreas(tb.allowedAreas());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
}
void tst_QToolBar::orientation()
@@ -271,48 +248,48 @@ void tst_QToolBar::orientation()
tb.setOrientation(Qt::Vertical);
QCOMPARE(tb.orientation(), Qt::Vertical);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const Qt::Orientation *>(spy.at(0).value(0).constData()),
tb.orientation());
spy.clear();
tb.setOrientation(tb.orientation());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
tb.setOrientation(Qt::Horizontal);
QCOMPARE(tb.orientation(), Qt::Horizontal);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const Qt::Orientation *>(spy.at(0).value(0).constData()),
tb.orientation());
spy.clear();
tb.setOrientation(tb.orientation());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
tb.setOrientation(Qt::Vertical);
QCOMPARE(tb.orientation(), Qt::Vertical);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const Qt::Orientation *>(spy.at(0).value(0).constData()),
tb.orientation());
spy.clear();
tb.setOrientation(tb.orientation());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
tb.setOrientation(Qt::Horizontal);
QCOMPARE(tb.orientation(), Qt::Horizontal);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const Qt::Orientation *>(spy.at(0).value(0).constData()),
tb.orientation());
spy.clear();
tb.setOrientation(tb.orientation());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
tb.setOrientation(Qt::Vertical);
QCOMPARE(tb.orientation(), Qt::Vertical);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const Qt::Orientation *>(spy.at(0).value(0).constData()),
tb.orientation());
spy.clear();
tb.setOrientation(tb.orientation());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
}
void tst_QToolBar::addAction()
@@ -322,13 +299,13 @@ void tst_QToolBar::addAction()
{
QAction action(0);
- QCOMPARE(tb.actions().count(), 0);
+ QCOMPARE(tb.actions().size(), 0);
tb.addAction(&action);
- QCOMPARE(tb.actions().count(), 1);
+ QCOMPARE(tb.actions().size(), 1);
QCOMPARE(tb.actions()[0], &action);
tb.clear();
- QCOMPARE(tb.actions().count(), 0);
+ QCOMPARE(tb.actions().size(), 0);
}
{
@@ -351,14 +328,14 @@ void tst_QToolBar::addAction()
QCOMPARE(icon, action4->icon());
QCOMPARE(text, action4->text());
- QCOMPARE(tb.actions().count(), 4);
+ QCOMPARE(tb.actions().size(), 4);
QCOMPARE(tb.actions()[0], action1);
QCOMPARE(tb.actions()[1], action2);
QCOMPARE(tb.actions()[2], action3);
QCOMPARE(tb.actions()[3], action4);
tb.clear();
- QCOMPARE(tb.actions().count(), 0);
+ QCOMPARE(tb.actions().size(), 0);
}
}
@@ -387,19 +364,19 @@ void tst_QToolBar::insertAction()
QAction action3(0);
QAction action4(0);
- QCOMPARE(tb.actions().count(), 0);
+ QCOMPARE(tb.actions().size(), 0);
tb.insertAction(0, &action1);
tb.insertAction(&action1, &action2);
tb.insertAction(&action2, &action3);
tb.insertAction(&action3, &action4);
- QCOMPARE(tb.actions().count(), 4);
+ QCOMPARE(tb.actions().size(), 4);
QCOMPARE(tb.actions()[0], &action4);
QCOMPARE(tb.actions()[1], &action3);
QCOMPARE(tb.actions()[2], &action2);
QCOMPARE(tb.actions()[3], &action1);
tb.clear();
- QCOMPARE(tb.actions().count(), 0);
+ QCOMPARE(tb.actions().size(), 0);
}
void tst_QToolBar::addSeparator()
@@ -413,13 +390,13 @@ void tst_QToolBar::addSeparator()
QAction *sep = tb.addSeparator();
tb.addAction(&action2);
- QCOMPARE(tb.actions().count(), 3);
+ QCOMPARE(tb.actions().size(), 3);
QCOMPARE(tb.actions()[0], &action1);
QCOMPARE(tb.actions()[1], sep);
QCOMPARE(tb.actions()[2], &action2);
tb.clear();
- QCOMPARE(tb.actions().count(), 0);
+ QCOMPARE(tb.actions().size(), 0);
}
void tst_QToolBar::insertSeparator()
@@ -433,13 +410,13 @@ void tst_QToolBar::insertSeparator()
tb.addAction(&action2);
QAction *sep = tb.insertSeparator(&action2);
- QCOMPARE(tb.actions().count(), 3);
+ QCOMPARE(tb.actions().size(), 3);
QCOMPARE(tb.actions()[0], &action1);
QCOMPARE(tb.actions()[1], sep);
QCOMPARE(tb.actions()[2], &action2);
tb.clear();
- QCOMPARE(tb.actions().count(), 0);
+ QCOMPARE(tb.actions().size(), 0);
}
void tst_QToolBar::addWidget()
@@ -454,7 +431,7 @@ void tst_QToolBar::addWidget()
QAction *widget = tb.addWidget(&w);
tb.addAction(&action2);
- QCOMPARE(tb.actions().count(), 3);
+ QCOMPARE(tb.actions().size(), 3);
QCOMPARE(tb.actions()[0], &action1);
QCOMPARE(tb.actions()[1], widget);
QCOMPARE(tb.actions()[2], &action2);
@@ -462,18 +439,18 @@ void tst_QToolBar::addWidget()
// it should be possible to reuse the action returned by
// addWidget() to place the widget somewhere else in the toolbar
tb.removeAction(widget);
- QCOMPARE(tb.actions().count(), 2);
+ QCOMPARE(tb.actions().size(), 2);
QCOMPARE(tb.actions()[0], &action1);
QCOMPARE(tb.actions()[1], &action2);
tb.addAction(widget);
- QCOMPARE(tb.actions().count(), 3);
+ QCOMPARE(tb.actions().size(), 3);
QCOMPARE(tb.actions()[0], &action1);
QCOMPARE(tb.actions()[1], &action2);
QCOMPARE(tb.actions()[2], widget);
tb.clear();
- QCOMPARE(tb.actions().count(), 0);
+ QCOMPARE(tb.actions().size(), 0);
}
void tst_QToolBar::insertWidget()
@@ -488,7 +465,7 @@ void tst_QToolBar::insertWidget()
tb.addAction(&action2);
QAction *widget = tb.insertWidget(&action2, &w);
- QCOMPARE(tb.actions().count(), 3);
+ QCOMPARE(tb.actions().size(), 3);
QCOMPARE(tb.actions()[0], &action1);
QCOMPARE(tb.actions()[1], widget);
QCOMPARE(tb.actions()[2], &action2);
@@ -496,18 +473,18 @@ void tst_QToolBar::insertWidget()
// it should be possible to reuse the action returned by
// addWidget() to place the widget somewhere else in the toolbar
tb.removeAction(widget);
- QCOMPARE(tb.actions().count(), 2);
+ QCOMPARE(tb.actions().size(), 2);
QCOMPARE(tb.actions()[0], &action1);
QCOMPARE(tb.actions()[1], &action2);
tb.insertAction(&action1, widget);
- QCOMPARE(tb.actions().count(), 3);
+ QCOMPARE(tb.actions().size(), 3);
QCOMPARE(tb.actions()[0], widget);
QCOMPARE(tb.actions()[1], &action1);
QCOMPARE(tb.actions()[2], &action2);
tb.clear();
- QCOMPARE(tb.actions().count(), 0);
+ QCOMPARE(tb.actions().size(), 0);
{
QToolBar tb;
@@ -649,43 +626,43 @@ void tst_QToolBar::iconSize()
QCOMPARE(tb.iconSize(), defaultIconSize);
tb.setIconSize(defaultIconSize);
QCOMPARE(tb.iconSize(), defaultIconSize);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
spy.clear();
tb.setIconSize(largeIconSize);
QCOMPARE(tb.iconSize(), largeIconSize);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.first().first().toSize(), largeIconSize);
// no-op
spy.clear();
tb.setIconSize(largeIconSize);
QCOMPARE(tb.iconSize(), largeIconSize);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
spy.clear();
tb.setIconSize(defaultIconSize);
QCOMPARE(tb.iconSize(), defaultIconSize);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.first().first().toSize(), defaultIconSize);
// no-op
spy.clear();
tb.setIconSize(defaultIconSize);
QCOMPARE(tb.iconSize(), defaultIconSize);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
spy.clear();
tb.setIconSize(smallIconSize);
QCOMPARE(tb.iconSize(), smallIconSize);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.first().first().toSize(), smallIconSize);
// no-op
spy.clear();
tb.setIconSize(smallIconSize);
QCOMPARE(tb.iconSize(), smallIconSize);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
// setting the icon size to an invalid QSize will reset the
// iconSize property to the default
@@ -713,28 +690,28 @@ void tst_QToolBar::iconSize()
// explicitly set it to the default
tb.setIconSize(defaultIconSize);
QCOMPARE(tb.iconSize(), defaultIconSize);
- QCOMPARE(tbSpy.count(), 0);
+ QCOMPARE(tbSpy.size(), 0);
mw.addToolBar(&tb);
// tb icon size should not change since it has been explicitly set
QCOMPARE(tb.iconSize(), defaultIconSize);
- QCOMPARE(tbSpy.count(), 0);
+ QCOMPARE(tbSpy.size(), 0);
mw.setIconSize(largeIconSize);
QCOMPARE(tb.iconSize(), defaultIconSize);
- QCOMPARE(tbSpy.count(), 0);
+ QCOMPARE(tbSpy.size(), 0);
mw.setIconSize(defaultIconSize);
QCOMPARE(tb.iconSize(), defaultIconSize);
- QCOMPARE(tbSpy.count(), 0);
+ QCOMPARE(tbSpy.size(), 0);
mw.setIconSize(smallIconSize);
QCOMPARE(tb.iconSize(), defaultIconSize);
- QCOMPARE(tbSpy.count(), 0);
+ QCOMPARE(tbSpy.size(), 0);
// resetting to the default should cause the toolbar to take
// on the mainwindow's icon size
@@ -757,51 +734,51 @@ void tst_QToolBar::toolButtonStyle()
QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonIconOnly);
tb.setToolButtonStyle(Qt::ToolButtonIconOnly);
QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonIconOnly);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
tb.setToolButtonStyle(Qt::ToolButtonTextOnly);
QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonTextOnly);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
// no-op
tb.setToolButtonStyle(Qt::ToolButtonTextOnly);
QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonTextOnly);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
tb.setToolButtonStyle(Qt::ToolButtonIconOnly);
QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonIconOnly);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
// no-op
tb.setToolButtonStyle(Qt::ToolButtonIconOnly);
QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonIconOnly);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
tb.setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonTextBesideIcon);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
// no-op
tb.setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonTextBesideIcon);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
tb.setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonTextUnderIcon);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
// no-op
tb.setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonTextUnderIcon);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
tb.setToolButtonStyle(Qt::ToolButtonFollowStyle);
QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonFollowStyle);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
}
{
@@ -815,28 +792,28 @@ void tst_QToolBar::toolButtonStyle()
// explicitly set the tb to the default
tb.setToolButtonStyle(Qt::ToolButtonIconOnly);
QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonIconOnly);
- QCOMPARE(tbSpy.count(), 0);
+ QCOMPARE(tbSpy.size(), 0);
mw.addToolBar(&tb);
// tb icon size should not change since it has been explicitly set
QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonIconOnly);
- QCOMPARE(tbSpy.count(), 0);
+ QCOMPARE(tbSpy.size(), 0);
mw.setToolButtonStyle(Qt::ToolButtonIconOnly);
QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonIconOnly);
- QCOMPARE(tbSpy.count(), 0);
+ QCOMPARE(tbSpy.size(), 0);
mw.setToolButtonStyle(Qt::ToolButtonTextOnly);
QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonIconOnly);
- QCOMPARE(tbSpy.count(), 0);
+ QCOMPARE(tbSpy.size(), 0);
mw.setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonIconOnly);
- QCOMPARE(tbSpy.count(), 0);
+ QCOMPARE(tbSpy.size(), 0);
// note: there is no way to clear the explicitly set tool
// button style... once you explicitly set it, the toolbar
@@ -950,25 +927,25 @@ void tst_QToolBar::visibilityChanged()
mw.addToolBar(&tb);
mw.show();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.at(0).at(0).toBool(), true);
spy.clear();
tb.hide();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.at(0).at(0).toBool(), false);
spy.clear();
tb.hide();
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
tb.show();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.at(0).at(0).toBool(), true);
spy.clear();
tb.show();
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
}
void tst_QToolBar::actionOwnership()
@@ -1045,12 +1022,12 @@ void tst_QToolBar::accel()
QSignalSpy spy(action, SIGNAL(triggered(bool)));
mw.show();
- QApplication::setActiveWindow(&mw);
+ QApplicationPrivate::setActiveWindow(&mw);
QVERIFY(QTest::qWaitForWindowActive(&mw));
QTest::keyClick(&mw, Qt::Key_T, Qt::AltModifier);
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
#ifdef Q_OS_MAC
qt_set_sequence_auto_mnemonic(false);
#endif
diff --git a/tests/auto/widgets/widgets/qtoolbox/CMakeLists.txt b/tests/auto/widgets/widgets/qtoolbox/CMakeLists.txt
index bb50233c6e..362fba25a4 100644
--- a/tests/auto/widgets/widgets/qtoolbox/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qtoolbox/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qtoolbox.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qtoolbox Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtoolbox LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qtoolbox
SOURCES
tst_qtoolbox.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
)
diff --git a/tests/auto/widgets/widgets/qtoolbox/tst_qtoolbox.cpp b/tests/auto/widgets/widgets/qtoolbox/tst_qtoolbox.cpp
index fc7eade9f4..fb14ceb79c 100644
--- a/tests/auto/widgets/widgets/qtoolbox/tst_qtoolbox.cpp
+++ b/tests/auto/widgets/widgets/qtoolbox/tst_qtoolbox.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>
diff --git a/tests/auto/widgets/widgets/qtoolbutton/CMakeLists.txt b/tests/auto/widgets/widgets/qtoolbutton/CMakeLists.txt
index b27d88f503..7c8b41b5e6 100644
--- a/tests/auto/widgets/widgets/qtoolbutton/CMakeLists.txt
+++ b/tests/auto/widgets/widgets/qtoolbutton/CMakeLists.txt
@@ -1,13 +1,21 @@
-# Generated from qtoolbutton.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qtoolbutton Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtoolbutton LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qtoolbutton
SOURCES
tst_qtoolbutton.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
+ Qt::WidgetsPrivate
)
diff --git a/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp b/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp
index 12a9ec3de0..20472861d9 100644
--- a/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp
+++ b/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.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>
@@ -40,6 +15,8 @@
#include <qscreen.h>
#include <qlabel.h>
+#include <QtWidgets/private/qapplication_p.h>
+
class tst_QToolButton : public QObject
{
Q_OBJECT
@@ -57,6 +34,7 @@ private slots:
void qtbug_26956_popupTimerDone();
void qtbug_34759_sizeHintResetWhenSettingMenu();
void defaultActionSynced();
+ void deleteInHandler();
protected slots:
void sendMouseClick();
@@ -143,11 +121,11 @@ void tst_QToolButton::triggered()
toolButton->setDefaultAction(defaultAction);
mainWidget.show();
- QApplication::setActiveWindow(&mainWidget);
+ QApplicationPrivate::setActiveWindow(&mainWidget);
QVERIFY(QTest::qWaitForWindowActive(&mainWidget));
defaultAction->trigger();
- QCOMPARE(spy.count(),1);
+ QCOMPARE(spy.size(),1);
QCOMPARE(qvariant_cast<QAction *>(spy.at(0).at(0)), defaultAction);
m_menu = menu.data();
@@ -158,7 +136,7 @@ void tst_QToolButton::triggered()
timer->start();
QTimer::singleShot(10000, &mainWidget, SLOT(close())); // Emergency bail-out
toolButton->showMenu();
- QTRY_COMPARE(spy.count(),2);
+ QTRY_COMPARE(spy.size(),2);
QCOMPARE(qvariant_cast<QAction *>(spy.at(1).at(0)), one);
}
@@ -204,14 +182,14 @@ void tst_QToolButton::task176137_autoRepeatOfAction()
label->move(0, 50);
mainWidget.show();
- QApplication::setActiveWindow(&mainWidget);
+ QApplicationPrivate::setActiveWindow(&mainWidget);
QVERIFY(QTest::qWaitForWindowActive(&mainWidget));
QSignalSpy spy(&action,SIGNAL(triggered()));
QTest::mousePress (toolButton, Qt::LeftButton);
QTest::qWait(2000);
QTest::mouseRelease (toolButton, Qt::LeftButton, {}, {});
- QCOMPARE(spy.count(),1);
+ QCOMPARE(spy.size(),1);
// try again with auto repeat
toolButton->setAutoRepeat (true);
@@ -221,11 +199,11 @@ void tst_QToolButton::task176137_autoRepeatOfAction()
QTest::mouseRelease (toolButton, Qt::LeftButton, {}, {});
const qreal expected = (3000 - toolButton->autoRepeatDelay()) / toolButton->autoRepeatInterval() + 1;
//we check that the difference is small (on some systems timers are not super accurate)
- qreal diff = (expected - repeatSpy.count()) / expected;
+ qreal diff = (expected - repeatSpy.size()) / expected;
QVERIFY2(qAbs(diff) < 0.2, qPrintable(
QString("expected: %1, actual: %2, diff (fraction): %3")
.arg(expected)
- .arg(repeatSpy.count())
+ .arg(repeatSpy.size())
.arg(diff)));
}
@@ -298,21 +276,21 @@ void tst_QToolButton::defaultActionSynced()
tb.setChecked(true);
QVERIFY(a.isChecked());
- QCOMPARE(tbSpy.count(), ++tbToggledCount);
- QCOMPARE(aSpy.count(), ++aToggledCount);
+ QCOMPARE(tbSpy.size(), ++tbToggledCount);
+ QCOMPARE(aSpy.size(), ++aToggledCount);
tb.setChecked(false);
QVERIFY(!a.isChecked());
- QCOMPARE(tbSpy.count(), ++tbToggledCount);
- QCOMPARE(aSpy.count(), ++aToggledCount);
+ QCOMPARE(tbSpy.size(), ++tbToggledCount);
+ QCOMPARE(aSpy.size(), ++aToggledCount);
a.setChecked(true);
QVERIFY(tb.isChecked());
- QCOMPARE(tbSpy.count(), ++tbToggledCount);
- QCOMPARE(aSpy.count(), ++aToggledCount);
+ QCOMPARE(tbSpy.size(), ++tbToggledCount);
+ QCOMPARE(aSpy.size(), ++aToggledCount);
a.setChecked(false);
QVERIFY(!tb.isChecked());
- QCOMPARE(tbSpy.count(), ++tbToggledCount);
- QCOMPARE(aSpy.count(), ++aToggledCount);
+ QCOMPARE(tbSpy.size(), ++tbToggledCount);
+ QCOMPARE(aSpy.size(), ++aToggledCount);
QAction b;
QSignalSpy bSpy(&b, SIGNAL(toggled(bool)));
@@ -326,17 +304,34 @@ void tst_QToolButton::defaultActionSynced()
QVERIFY(!a.isChecked());
QVERIFY(b.isChecked());
- QCOMPARE(tbSpy.count(), ++tbToggledCount);
- QCOMPARE(aSpy.count(), aToggledCount);
- QCOMPARE(bSpy.count(), ++bToggledCount);
+ QCOMPARE(tbSpy.size(), ++tbToggledCount);
+ QCOMPARE(aSpy.size(), aToggledCount);
+ QCOMPARE(bSpy.size(), ++bToggledCount);
tb.click();
QVERIFY(!a.isChecked());
QVERIFY(!tb.isChecked());
QVERIFY(!b.isChecked());
- QCOMPARE(tbSpy.count(), ++tbToggledCount);
- QCOMPARE(aSpy.count(), aToggledCount);
- QCOMPARE(bSpy.count(), ++bToggledCount);
+ QCOMPARE(tbSpy.size(), ++tbToggledCount);
+ QCOMPARE(aSpy.size(), aToggledCount);
+ QCOMPARE(bSpy.size(), ++bToggledCount);
+}
+
+void tst_QToolButton::deleteInHandler()
+{
+ // Tests that if something deletes the button
+ // while its event handler is still on the callstack, we don't crash
+
+ QPointer<QToolButton> tb = new QToolButton();
+ tb->show();
+ QVERIFY(QTest::qWaitForWindowActive(tb));
+
+ connect(tb, &QToolButton::clicked, this, [tb] {
+ delete tb;
+ });
+
+ QTest::mouseClick(tb, Qt::LeftButton);
+ QVERIFY(!tb);
}
QTEST_MAIN(tst_QToolButton)