summaryrefslogtreecommitdiffstats
path: root/tests/auto/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/widgets')
-rw-r--r--tests/auto/widgets/dialogs/dialogs.pro18
-rw-r--r--tests/auto/widgets/dialogs/qabstractprintdialog/.gitignore1
-rw-r--r--tests/auto/widgets/dialogs/qabstractprintdialog/qabstractprintdialog.pro9
-rw-r--r--tests/auto/widgets/dialogs/qabstractprintdialog/tst_qabstractprintdialog.cpp146
-rw-r--r--tests/auto/widgets/dialogs/qcolordialog/.gitignore1
-rw-r--r--tests/auto/widgets/dialogs/qcolordialog/qcolordialog.pro6
-rw-r--r--tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp164
-rw-r--r--tests/auto/widgets/dialogs/qdialog/.gitignore1
-rw-r--r--tests/auto/widgets/dialogs/qdialog/qdialog.pro5
-rw-r--r--tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp609
-rw-r--r--tests/auto/widgets/dialogs/qerrormessage/.gitignore1
-rw-r--r--tests/auto/widgets/dialogs/qerrormessage/qerrormessage.pro10
-rw-r--r--tests/auto/widgets/dialogs/qerrormessage/tst_qerrormessage.cpp158
-rw-r--r--tests/auto/widgets/dialogs/qfiledialog/.gitignore1
-rw-r--r--tests/auto/widgets/dialogs/qfiledialog/qfiledialog.pro23
-rw-r--r--tests/auto/widgets/dialogs/qfiledialog/resources/file.txt1
-rw-r--r--tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp1349
-rw-r--r--tests/auto/widgets/dialogs/qfiledialog2/qfiledialog2.pro20
-rw-r--r--tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp1213
-rw-r--r--tests/auto/widgets/dialogs/qfilesystemmodel/.gitignore1
-rw-r--r--tests/auto/widgets/dialogs/qfilesystemmodel/qfilesystemmodel.pro7
-rw-r--r--tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp1046
-rw-r--r--tests/auto/widgets/dialogs/qfontdialog/.gitignore1
-rw-r--r--tests/auto/widgets/dialogs/qfontdialog/qfontdialog.pro12
-rw-r--r--tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp186
-rw-r--r--tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog_mac_helpers.mm67
-rw-r--r--tests/auto/widgets/dialogs/qinputdialog/.gitignore1
-rw-r--r--tests/auto/widgets/dialogs/qinputdialog/qinputdialog.pro5
-rw-r--r--tests/auto/widgets/dialogs/qinputdialog/tst_qinputdialog.cpp430
-rw-r--r--tests/auto/widgets/dialogs/qmessagebox/.gitignore1
-rw-r--r--tests/auto/widgets/dialogs/qmessagebox/qmessagebox.pro9
-rw-r--r--tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp674
-rw-r--r--tests/auto/widgets/dialogs/qprogressdialog/.gitignore1
-rw-r--r--tests/auto/widgets/dialogs/qprogressdialog/qprogressdialog.pro9
-rw-r--r--tests/auto/widgets/dialogs/qprogressdialog/tst_qprogressdialog.cpp157
-rw-r--r--tests/auto/widgets/dialogs/qsidebar/.gitignore1
-rw-r--r--tests/auto/widgets/dialogs/qsidebar/qsidebar.pro6
-rw-r--r--tests/auto/widgets/dialogs/qsidebar/tst_qsidebar.cpp231
-rw-r--r--tests/auto/widgets/dialogs/qwizard/.gitignore1
-rw-r--r--tests/auto/widgets/dialogs/qwizard/images/background.pngbin0 -> 22932 bytes
-rw-r--r--tests/auto/widgets/dialogs/qwizard/images/banner.pngbin0 -> 4230 bytes
-rw-r--r--tests/auto/widgets/dialogs/qwizard/images/logo.pngbin0 -> 1661 bytes
-rw-r--r--tests/auto/widgets/dialogs/qwizard/images/watermark.pngbin0 -> 15788 bytes
-rw-r--r--tests/auto/widgets/dialogs/qwizard/qwizard.pro4
-rw-r--r--tests/auto/widgets/dialogs/qwizard/qwizard.qrc8
-rw-r--r--tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp2645
-rw-r--r--tests/auto/widgets/effects/effects.pro4
-rw-r--r--tests/auto/widgets/effects/qgraphicseffect/qgraphicseffect.pro7
-rw-r--r--tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp760
-rw-r--r--tests/auto/widgets/graphicsview/graphicsview.pro32
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsanchorlayout/qgraphicsanchorlayout.pro5
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp2091
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsanchorlayout1/qgraphicsanchorlayout1.pro5
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp3111
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicseffectsource/qgraphicseffectsource.pro7
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicseffectsource/tst_qgraphicseffectsource.cpp422
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsgridlayout/.gitignore1
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsgridlayout/qgraphicsgridlayout.pro6
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp3465
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsitem/.gitignore1
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsitem/qgraphicsitem.pro9
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp11402
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsitemanimation/.gitignore1
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsitemanimation/qgraphicsitemanimation.pro6
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsitemanimation/tst_qgraphicsitemanimation.cpp192
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicslayout/.gitignore1
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicslayout/qgraphicslayout.pro9
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp992
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicslayoutitem/.gitignore1
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicslayoutitem/qgraphicslayoutitem.pro5
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicslayoutitem/tst_qgraphicslayoutitem.cpp376
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicslinearlayout/.gitignore1
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicslinearlayout/qgraphicslinearlayout.pro5
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp1650
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsobject/qgraphicsobject.pro7
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsobject/tst_qgraphicsobject.cpp297
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicspixmapitem/.gitignore1
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicspixmapitem/qgraphicspixmapitem.pro5
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicspixmapitem/tst_qgraphicspixmapitem.cpp427
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicspolygonitem/.gitignore1
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicspolygonitem/qgraphicspolygonitem.pro5
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicspolygonitem/tst_qgraphicspolygonitem.cpp349
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsproxywidget/.gitignore1
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsproxywidget/qgraphicsproxywidget.pro8
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp3649
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/.gitignore1
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/Ash_European.jpgbin0 -> 4751 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/graphicsScene_selection.databin0 -> 854488 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/images.qrc5
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/qgraphicsscene.pro20
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/all-all-45-deg-left.pngbin0 -> 2181 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/all-all-45-deg-right.pngbin0 -> 1953 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/all-all-scale-2x.pngbin0 -> 2399 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/all-all-translate-0-50.pngbin0 -> 1872 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/all-all-translate-50-0.pngbin0 -> 1884 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/all-all-untransformed-clip-ellipse.pngbin0 -> 1819 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/all-all-untransformed-clip-rect.pngbin0 -> 1255 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/all-all-untransformed.pngbin0 -> 1896 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/all-bottomleft-untransformed.pngbin0 -> 1560 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/all-bottomright-untransformed.pngbin0 -> 1550 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/all-topleft-untransformed.pngbin0 -> 1566 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/all-topright-untransformed.pngbin0 -> 1547 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/bottom-bottomright-untransformed.pngbin0 -> 1172 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/bottom-topleft-untransformed.pngbin0 -> 1690 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/bottomleft-all-untransformed.pngbin0 -> 1736 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/bottomleft-topleft-untransformed.pngbin0 -> 1642 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/bottomright-all-untransformed.pngbin0 -> 1093 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/bottomright-topleft-untransformed.pngbin0 -> 1661 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/left-bottomright-untransformed.pngbin0 -> 1289 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/left-topleft-untransformed.pngbin0 -> 1823 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/right-bottomright-untransformed.pngbin0 -> 1236 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/right-topleft-untransformed.pngbin0 -> 1839 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/top-bottomright-untransformed.pngbin0 -> 1174 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/top-topleft-untransformed.pngbin0 -> 1703 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/topleft-all-untransformed.pngbin0 -> 1973 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/topleft-topleft-untransformed.pngbin0 -> 1650 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/topright-all-untransformed.pngbin0 -> 2018 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/testData/render/topright-topleft-untransformed.pngbin0 -> 1669 bytes
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp4710
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicssceneindex/qgraphicssceneindex.pro6
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicssceneindex/tst_qgraphicssceneindex.cpp366
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicstransform/qgraphicstransform.pro6
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicstransform/tst_qgraphicstransform.cpp408
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsview/.gitignore1
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsview/qgraphicsview.pro9
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp4558
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview_2.cpp976
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicswidget/.gitignore1
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicswidget/qgraphicswidget.pro10
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp3361
-rw-r--r--tests/auto/widgets/itemviews/itemviews.pro33
-rw-r--r--tests/auto/widgets/itemviews/qabstractitemview/.gitignore1
-rw-r--r--tests/auto/widgets/itemviews/qabstractitemview/qabstractitemview.pro3
-rw-r--r--tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp1504
-rw-r--r--tests/auto/widgets/itemviews/qabstractproxymodel/.gitignore1
-rw-r--r--tests/auto/widgets/itemviews/qabstractproxymodel/qabstractproxymodel.pro3
-rw-r--r--tests/auto/widgets/itemviews/qabstractproxymodel/tst_qabstractproxymodel.cpp449
-rw-r--r--tests/auto/widgets/itemviews/qcolumnview/.gitignore1
-rw-r--r--tests/auto/widgets/itemviews/qcolumnview/qcolumnview.pro6
-rw-r--r--tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp1040
-rw-r--r--tests/auto/widgets/itemviews/qdatawidgetmapper/.gitignore1
-rw-r--r--tests/auto/widgets/itemviews/qdatawidgetmapper/qdatawidgetmapper.pro5
-rw-r--r--tests/auto/widgets/itemviews/qdatawidgetmapper/tst_qdatawidgetmapper.cpp411
-rw-r--r--tests/auto/widgets/itemviews/qdirmodel/.gitignore1
-rw-r--r--tests/auto/widgets/itemviews/qdirmodel/dirtest/test1/dummy1
-rw-r--r--tests/auto/widgets/itemviews/qdirmodel/dirtest/test1/test0
-rw-r--r--tests/auto/widgets/itemviews/qdirmodel/qdirmodel.pro20
-rw-r--r--tests/auto/widgets/itemviews/qdirmodel/test/file01.tst0
-rw-r--r--tests/auto/widgets/itemviews/qdirmodel/test/file02.tst0
-rw-r--r--tests/auto/widgets/itemviews/qdirmodel/test/file03.tst0
-rw-r--r--tests/auto/widgets/itemviews/qdirmodel/test/file04.tst0
-rw-r--r--tests/auto/widgets/itemviews/qdirmodel/tst_qdirmodel.cpp698
-rw-r--r--tests/auto/widgets/itemviews/qfileiconprovider/.gitignore1
-rw-r--r--tests/auto/widgets/itemviews/qfileiconprovider/qfileiconprovider.pro5
-rw-r--r--tests/auto/widgets/itemviews/qfileiconprovider/tst_qfileiconprovider.cpp181
-rw-r--r--tests/auto/widgets/itemviews/qheaderview/.gitignore1
-rw-r--r--tests/auto/widgets/itemviews/qheaderview/qheaderview.pro8
-rw-r--r--tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp2135
-rw-r--r--tests/auto/widgets/itemviews/qidentityproxymodel/qidentityproxymodel.pro7
-rw-r--r--tests/auto/widgets/itemviews/qidentityproxymodel/tst_qidentityproxymodel.cpp333
-rw-r--r--tests/auto/widgets/itemviews/qitemdelegate/.gitignore1
-rw-r--r--tests/auto/widgets/itemviews/qitemdelegate/qitemdelegate.pro6
-rw-r--r--tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp1216
-rw-r--r--tests/auto/widgets/itemviews/qitemeditorfactory/.gitignore1
-rw-r--r--tests/auto/widgets/itemviews/qitemeditorfactory/qitemeditorfactory.pro5
-rw-r--r--tests/auto/widgets/itemviews/qitemeditorfactory/tst_qitemeditorfactory.cpp105
-rw-r--r--tests/auto/widgets/itemviews/qitemselectionmodel/.gitignore1
-rw-r--r--tests/auto/widgets/itemviews/qitemselectionmodel/qitemselectionmodel.pro5
-rw-r--r--tests/auto/widgets/itemviews/qitemselectionmodel/tst_qitemselectionmodel.cpp2714
-rw-r--r--tests/auto/widgets/itemviews/qitemview/.gitignore1
-rw-r--r--tests/auto/widgets/itemviews/qitemview/qitemview.pro5
-rw-r--r--tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp928
-rw-r--r--tests/auto/widgets/itemviews/qitemview/viewstotest.cpp165
-rw-r--r--tests/auto/widgets/itemviews/qlistview/.gitignore1
-rw-r--r--tests/auto/widgets/itemviews/qlistview/qlistview.pro6
-rw-r--r--tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp2073
-rw-r--r--tests/auto/widgets/itemviews/qlistwidget/.gitignore1
-rw-r--r--tests/auto/widgets/itemviews/qlistwidget/qlistwidget.pro6
-rw-r--r--tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp1685
-rw-r--r--tests/auto/widgets/itemviews/qsortfilterproxymodel/.gitignore1
-rw-r--r--tests/auto/widgets/itemviews/qsortfilterproxymodel/qsortfilterproxymodel.pro8
-rw-r--r--tests/auto/widgets/itemviews/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp3274
-rw-r--r--tests/auto/widgets/itemviews/qstandarditem/.gitignore1
-rw-r--r--tests/auto/widgets/itemviews/qstandarditem/qstandarditem.pro5
-rw-r--r--tests/auto/widgets/itemviews/qstandarditem/tst_qstandarditem.cpp1110
-rw-r--r--tests/auto/widgets/itemviews/qstandarditemmodel/.gitignore1
-rw-r--r--tests/auto/widgets/itemviews/qstandarditemmodel/qstandarditemmodel.pro8
-rw-r--r--tests/auto/widgets/itemviews/qstandarditemmodel/tst_qstandarditemmodel.cpp1666
-rw-r--r--tests/auto/widgets/itemviews/qstringlistmodel/.gitignore1
-rw-r--r--tests/auto/widgets/itemviews/qstringlistmodel/qmodellistener.h75
-rw-r--r--tests/auto/widgets/itemviews/qstringlistmodel/qstringlistmodel.pro8
-rw-r--r--tests/auto/widgets/itemviews/qstringlistmodel/tst_qstringlistmodel.cpp286
-rw-r--r--tests/auto/widgets/itemviews/qtableview/.gitignore1
-rw-r--r--tests/auto/widgets/itemviews/qtableview/qtableview.pro7
-rw-r--r--tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp4075
-rw-r--r--tests/auto/widgets/itemviews/qtablewidget/.gitignore1
-rw-r--r--tests/auto/widgets/itemviews/qtablewidget/qtablewidget.pro3
-rw-r--r--tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp1500
-rw-r--r--tests/auto/widgets/itemviews/qtreeview/.gitignore1
-rw-r--r--tests/auto/widgets/itemviews/qtreeview/qtreeview.pro3
-rw-r--r--tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp3942
-rw-r--r--tests/auto/widgets/itemviews/qtreewidget/.gitignore1
-rw-r--r--tests/auto/widgets/itemviews/qtreewidget/qtreewidget.pro3
-rw-r--r--tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp3349
-rw-r--r--tests/auto/widgets/itemviews/qtreewidgetitemiterator/.gitignore1
-rw-r--r--tests/auto/widgets/itemviews/qtreewidgetitemiterator/qtreewidgetitemiterator.pro5
-rw-r--r--tests/auto/widgets/itemviews/qtreewidgetitemiterator/tst_qtreewidgetitemiterator.cpp1243
-rw-r--r--tests/auto/widgets/kernel/kernel.pro17
-rw-r--r--tests/auto/widgets/kernel/qaction/.gitignore1
-rw-r--r--tests/auto/widgets/kernel/qaction/qaction.pro5
-rw-r--r--tests/auto/widgets/kernel/qaction/tst_qaction.cpp373
-rw-r--r--tests/auto/widgets/kernel/qactiongroup/.gitignore1
-rw-r--r--tests/auto/widgets/kernel/qactiongroup/qactiongroup.pro5
-rw-r--r--tests/auto/widgets/kernel/qactiongroup/tst_qactiongroup.cpp247
-rw-r--r--tests/auto/widgets/kernel/qapplication/.gitignore3
-rw-r--r--tests/auto/widgets/kernel/qapplication/desktopsettingsaware/desktopsettingsaware.pro14
-rw-r--r--tests/auto/widgets/kernel/qapplication/desktopsettingsaware/main.cpp54
-rw-r--r--tests/auto/widgets/kernel/qapplication/heart.svg55
-rw-r--r--tests/auto/widgets/kernel/qapplication/modal/base.cpp62
-rw-r--r--tests/auto/widgets/kernel/qapplication/modal/base.h64
-rw-r--r--tests/auto/widgets/kernel/qapplication/modal/main.cpp54
-rw-r--r--tests/auto/widgets/kernel/qapplication/modal/modal.pro9
-rw-r--r--tests/auto/widgets/kernel/qapplication/qapplication.pro7
-rw-r--r--tests/auto/widgets/kernel/qapplication/test/test.pro27
-rw-r--r--tests/auto/widgets/kernel/qapplication/tmp/README3
-rw-r--r--tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp2107
-rw-r--r--tests/auto/widgets/kernel/qapplication/wincmdline/main.cpp53
-rw-r--r--tests/auto/widgets/kernel/qapplication/wincmdline/wincmdline.pro8
-rw-r--r--tests/auto/widgets/kernel/qboxlayout/.gitignore1
-rw-r--r--tests/auto/widgets/kernel/qboxlayout/qboxlayout.pro5
-rw-r--r--tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp280
-rw-r--r--tests/auto/widgets/kernel/qdesktopwidget/.gitignore1
-rw-r--r--tests/auto/widgets/kernel/qdesktopwidget/qdesktopwidget.pro3
-rw-r--r--tests/auto/widgets/kernel/qdesktopwidget/tst_qdesktopwidget.cpp187
-rw-r--r--tests/auto/widgets/kernel/qformlayout/.gitignore1
-rw-r--r--tests/auto/widgets/kernel/qformlayout/qformlayout.pro3
-rw-r--r--tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp913
-rw-r--r--tests/auto/widgets/kernel/qgridlayout/.gitignore1
-rw-r--r--tests/auto/widgets/kernel/qgridlayout/qgridlayout.pro10
-rw-r--r--tests/auto/widgets/kernel/qgridlayout/sortdialog.ui135
-rw-r--r--tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp1646
-rw-r--r--tests/auto/widgets/kernel/qinputcontext/qinputcontext.pro7
-rw-r--r--tests/auto/widgets/kernel/qinputcontext/tst_qinputcontext.cpp398
-rw-r--r--tests/auto/widgets/kernel/qlayout/.gitignore1
-rw-r--r--tests/auto/widgets/kernel/qlayout/baseline/smartmaxsize1792
-rw-r--r--tests/auto/widgets/kernel/qlayout/qlayout.pro16
-rw-r--r--tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp345
-rw-r--r--tests/auto/widgets/kernel/qsound/.gitignore1
-rw-r--r--tests/auto/widgets/kernel/qsound/4.wavbin0 -> 5538 bytes
-rw-r--r--tests/auto/widgets/kernel/qsound/qsound.pro10
-rw-r--r--tests/auto/widgets/kernel/qsound/tst_qsound.cpp88
-rw-r--r--tests/auto/widgets/kernel/qstackedlayout/.gitignore1
-rw-r--r--tests/auto/widgets/kernel/qstackedlayout/qstackedlayout.pro6
-rw-r--r--tests/auto/widgets/kernel/qstackedlayout/tst_qstackedlayout.cpp372
-rw-r--r--tests/auto/widgets/kernel/qtooltip/.gitignore1
-rw-r--r--tests/auto/widgets/kernel/qtooltip/qtooltip.pro5
-rw-r--r--tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp186
-rw-r--r--tests/auto/widgets/kernel/qwidget/.gitignore1
-rw-r--r--tests/auto/widgets/kernel/qwidget/geometry-fullscreen.datbin0 -> 46 bytes
-rw-r--r--tests/auto/widgets/kernel/qwidget/geometry-maximized.datbin0 -> 46 bytes
-rw-r--r--tests/auto/widgets/kernel/qwidget/geometry.datbin0 -> 46 bytes
-rw-r--r--tests/auto/widgets/kernel/qwidget/qwidget.pro23
-rw-r--r--tests/auto/widgets/kernel/qwidget/qwidget.qrc7
-rw-r--r--tests/auto/widgets/kernel/qwidget/testdata/paintEvent/res_Motif_data0.qsnapbin0 -> 722 bytes
-rw-r--r--tests/auto/widgets/kernel/qwidget/testdata/paintEvent/res_Motif_data1.qsnapbin0 -> 1509 bytes
-rw-r--r--tests/auto/widgets/kernel/qwidget/testdata/paintEvent/res_Motif_data2.qsnapbin0 -> 7965 bytes
-rw-r--r--tests/auto/widgets/kernel/qwidget/testdata/paintEvent/res_Motif_data3.qsnapbin0 -> 8265 bytes
-rw-r--r--tests/auto/widgets/kernel/qwidget/testdata/paintEvent/res_Windows_data0.qsnapbin0 -> 710 bytes
-rw-r--r--tests/auto/widgets/kernel/qwidget/testdata/paintEvent/res_Windows_data1.qsnapbin0 -> 1497 bytes
-rw-r--r--tests/auto/widgets/kernel/qwidget/testdata/paintEvent/res_Windows_data2.qsnapbin0 -> 7953 bytes
-rw-r--r--tests/auto/widgets/kernel/qwidget/testdata/paintEvent/res_Windows_data3.qsnapbin0 -> 8253 bytes
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp9472
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget_mac_helpers.h52
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget_mac_helpers.mm83
-rw-r--r--tests/auto/widgets/kernel/qwidget_window/.gitignore1
-rw-r--r--tests/auto/widgets/kernel/qwidget_window/qwidget_window.pro8
-rw-r--r--tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp326
-rw-r--r--tests/auto/widgets/kernel/qwidgetaction/.gitignore1
-rw-r--r--tests/auto/widgets/kernel/qwidgetaction/qwidgetaction.pro5
-rw-r--r--tests/auto/widgets/kernel/qwidgetaction/tst_qwidgetaction.cpp405
-rw-r--r--tests/auto/widgets/styles/qmacstyle/.gitignore1
-rw-r--r--tests/auto/widgets/styles/qmacstyle/qmacstyle.pro6
-rw-r--r--tests/auto/widgets/styles/qmacstyle/tst_qmacstyle.cpp413
-rw-r--r--tests/auto/widgets/styles/qstyle/.gitignore1
-rw-r--r--tests/auto/widgets/styles/qstyle/images/mac/button.pngbin0 -> 1785 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/mac/combobox.pngbin0 -> 1808 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/mac/lineedit.pngbin0 -> 953 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/mac/mdi.pngbin0 -> 3092 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/mac/menu.pngbin0 -> 1139 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/mac/radiobutton.pngbin0 -> 1498 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/mac/slider.pngbin0 -> 1074 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/mac/spinbox.pngbin0 -> 1299 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/vista/button.pngbin0 -> 722 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/vista/combobox.pngbin0 -> 809 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/vista/lineedit.pngbin0 -> 530 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/vista/menu.pngbin0 -> 646 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/vista/radiobutton.pngbin0 -> 844 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/vista/slider.pngbin0 -> 575 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/vista/spinbox.pngbin0 -> 583 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/qstyle.pro13
-rw-r--r--tests/auto/widgets/styles/qstyle/task_25863.pngbin0 -> 910 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/tst_qstyle.cpp794
-rw-r--r--tests/auto/widgets/styles/qstyleoption/.gitignore1
-rw-r--r--tests/auto/widgets/styles/qstyleoption/qstyleoption.pro11
-rw-r--r--tests/auto/widgets/styles/qstyleoption/tst_qstyleoption.cpp161
-rw-r--r--tests/auto/widgets/styles/qstylesheetstyle/.gitignore1
-rw-r--r--tests/auto/widgets/styles/qstylesheetstyle/images/testimage.pngbin0 -> 299 bytes
-rw-r--r--tests/auto/widgets/styles/qstylesheetstyle/qstylesheetstyle.pro7
-rw-r--r--tests/auto/widgets/styles/qstylesheetstyle/resources.qrc6
-rw-r--r--tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp1644
-rw-r--r--tests/auto/widgets/styles/styles.pro13
-rw-r--r--tests/auto/widgets/util/qcompleter/.gitignore1
-rw-r--r--tests/auto/widgets/util/qcompleter/qcompleter.pro11
-rw-r--r--tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp1519
-rw-r--r--tests/auto/widgets/util/qscroller/qscroller.pro4
-rw-r--r--tests/auto/widgets/util/qscroller/tst_qscroller.cpp530
-rw-r--r--tests/auto/widgets/util/qsystemtrayicon/.gitignore1
-rw-r--r--tests/auto/widgets/util/qsystemtrayicon/icons/icon.pngbin0 -> 1086 bytes
-rw-r--r--tests/auto/widgets/util/qsystemtrayicon/qsystemtrayicon.pro9
-rw-r--r--tests/auto/widgets/util/qsystemtrayicon/tst_qsystemtrayicon.cpp152
-rw-r--r--tests/auto/widgets/util/qundogroup/.gitignore1
-rw-r--r--tests/auto/widgets/util/qundogroup/qundogroup.pro4
-rw-r--r--tests/auto/widgets/util/qundogroup/testdata/qundogroup.ts25
-rw-r--r--tests/auto/widgets/util/qundogroup/tst_qundogroup.cpp668
-rw-r--r--tests/auto/widgets/util/qundostack/.gitignore1
-rw-r--r--tests/auto/widgets/util/qundostack/qundostack.pro4
-rw-r--r--tests/auto/widgets/util/qundostack/testdata/qundostack.ts25
-rw-r--r--tests/auto/widgets/util/qundostack/tst_qundostack.cpp3039
-rw-r--r--tests/auto/widgets/util/util.pro11
-rw-r--r--tests/auto/widgets/widgets.pro10
-rw-r--r--tests/auto/widgets/widgets/qabstractbutton/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qabstractbutton/qabstractbutton.pro5
-rw-r--r--tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp650
-rw-r--r--tests/auto/widgets/widgets/qabstractscrollarea/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qabstractscrollarea/qabstractscrollarea.pro9
-rw-r--r--tests/auto/widgets/widgets/qabstractscrollarea/tst_qabstractscrollarea.cpp390
-rw-r--r--tests/auto/widgets/widgets/qabstractslider/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qabstractslider/qabstractslider.pro5
-rw-r--r--tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp1247
-rw-r--r--tests/auto/widgets/widgets/qabstractspinbox/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qabstractspinbox/qabstractspinbox.pro9
-rw-r--r--tests/auto/widgets/widgets/qabstractspinbox/tst_qabstractspinbox.cpp163
-rw-r--r--tests/auto/widgets/widgets/qbuttongroup/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qbuttongroup/qbuttongroup.pro6
-rw-r--r--tests/auto/widgets/widgets/qbuttongroup/tst_qbuttongroup.cpp525
-rw-r--r--tests/auto/widgets/widgets/qcalendarwidget/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qcalendarwidget/qcalendarwidget.pro5
-rw-r--r--tests/auto/widgets/widgets/qcalendarwidget/tst_qcalendarwidget.cpp368
-rw-r--r--tests/auto/widgets/widgets/qcheckbox/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qcheckbox/qcheckbox.pro6
-rw-r--r--tests/auto/widgets/widgets/qcheckbox/tst_qcheckbox.cpp358
-rw-r--r--tests/auto/widgets/widgets/qcombobox/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qcombobox/qcombobox.pro3
-rw-r--r--tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp2579
-rw-r--r--tests/auto/widgets/widgets/qcommandlinkbutton/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro6
-rw-r--r--tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp590
-rw-r--r--tests/auto/widgets/widgets/qdatetimeedit/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qdatetimeedit/qdatetimeedit.pro8
-rw-r--r--tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp3458
-rw-r--r--tests/auto/widgets/widgets/qdial/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qdial/qdial.pro5
-rw-r--r--tests/auto/widgets/widgets/qdial/tst_qdial.cpp211
-rw-r--r--tests/auto/widgets/widgets/qdialogbuttonbox/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qdialogbuttonbox/qdialogbuttonbox.pro7
-rw-r--r--tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp810
-rw-r--r--tests/auto/widgets/widgets/qdockwidget/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qdockwidget/qdockwidget.pro7
-rw-r--r--tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp877
-rw-r--r--tests/auto/widgets/widgets/qdoublespinbox/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qdoublespinbox/qdoublespinbox.pro5
-rw-r--r--tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp1111
-rw-r--r--tests/auto/widgets/widgets/qdoublevalidator/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qdoublevalidator/qdoublevalidator.pro5
-rw-r--r--tests/auto/widgets/widgets/qdoublevalidator/tst_qdoublevalidator.cpp387
-rw-r--r--tests/auto/widgets/widgets/qfocusframe/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qfocusframe/qfocusframe.pro9
-rw-r--r--tests/auto/widgets/widgets/qfocusframe/tst_qfocusframe.cpp89
-rw-r--r--tests/auto/widgets/widgets/qfontcombobox/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qfontcombobox/qfontcombobox.pro5
-rw-r--r--tests/auto/widgets/widgets/qfontcombobox/tst_qfontcombobox.cpp303
-rw-r--r--tests/auto/widgets/widgets/qgroupbox/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro6
-rw-r--r--tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp475
-rw-r--r--tests/auto/widgets/widgets/qintvalidator/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qintvalidator/qintvalidator.pro4
-rw-r--r--tests/auto/widgets/widgets/qintvalidator/tst_qintvalidator.cpp255
-rw-r--r--tests/auto/widgets/widgets/qlabel/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qlabel/green.pngbin0 -> 97 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/qlabel.pro15
-rw-r--r--tests/auto/widgets/widgets/qlabel/red.pngbin0 -> 105 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/acc_01/res_Windows_data0.qsnapbin0 -> 328 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/acc_01/res_Windows_win32_data0.qsnapbin0 -> 330 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data0.qsnapbin0 -> 322 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data1.qsnapbin0 -> 328 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data10.qsnapbin0 -> 330 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data2.qsnapbin0 -> 324 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data3.qsnapbin0 -> 320 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data4.qsnapbin0 -> 322 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data5.qsnapbin0 -> 328 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data6.qsnapbin0 -> 330 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data7.qsnapbin0 -> 318 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data8.qsnapbin0 -> 324 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Motif_data9.qsnapbin0 -> 332 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data0.qsnapbin0 -> 316 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data1.qsnapbin0 -> 322 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data10.qsnapbin0 -> 324 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data2.qsnapbin0 -> 318 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data3.qsnapbin0 -> 314 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data4.qsnapbin0 -> 316 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data5.qsnapbin0 -> 322 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data6.qsnapbin0 -> 324 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data7.qsnapbin0 -> 312 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data8.qsnapbin0 -> 318 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_data9.qsnapbin0 -> 326 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data0.qsnapbin0 -> 318 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data1.qsnapbin0 -> 324 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data10.qsnapbin0 -> 326 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data2.qsnapbin0 -> 320 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data3.qsnapbin0 -> 316 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data4.qsnapbin0 -> 318 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data5.qsnapbin0 -> 324 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data6.qsnapbin0 -> 326 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data7.qsnapbin0 -> 314 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data8.qsnapbin0 -> 320 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setAlignment/alignRes_Windows_win32_data9.qsnapbin0 -> 328 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Motif_data0.qsnapbin0 -> 344 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Motif_data1.qsnapbin0 -> 346 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Motif_data2.qsnapbin0 -> 346 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_data0.qsnapbin0 -> 338 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_data1.qsnapbin0 -> 340 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_data2.qsnapbin0 -> 340 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_win32_data0.qsnapbin0 -> 340 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_win32_data1.qsnapbin0 -> 342 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setIndent/indentRes_Windows_win32_data2.qsnapbin0 -> 342 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setPixmap/Vpix_Motif_data0.qsnapbin0 -> 405 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setPixmap/Vpix_Windows_data0.qsnapbin0 -> 399 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setPixmap/Vpix_Windows_win32_data0.qsnapbin0 -> 397 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setPixmap/empty_Motif_data0.qsnapbin0 -> 257 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setPixmap/empty_Windows_data0.qsnapbin0 -> 251 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setPixmap/empty_Windows_win32_data0.qsnapbin0 -> 249 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setPixmap/scaledVpix_Motif_data0.qsnapbin0 -> 1040 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setPixmap/scaledVpix_Windows_data0.qsnapbin0 -> 1034 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setPixmap/scaledVpix_Windows_win32_data0.qsnapbin0 -> 984 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setText/res_Motif_data0.qsnapbin0 -> 352 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setText/res_Motif_data1.qsnapbin0 -> 398 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setText/res_Motif_data2.qsnapbin0 -> 448 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setText/res_Motif_data3.qsnapbin0 -> 744 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_data0.qsnapbin0 -> 346 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_data1.qsnapbin0 -> 392 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_data2.qsnapbin0 -> 442 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_data3.qsnapbin0 -> 738 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_win32_data0.qsnapbin0 -> 344 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_win32_data1.qsnapbin0 -> 390 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_win32_data2.qsnapbin0 -> 440 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/testdata/setText/res_Windows_win32_data3.qsnapbin0 -> 736 bytes
-rw-r--r--tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp581
-rw-r--r--tests/auto/widgets/widgets/qlcdnumber/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qlcdnumber/qlcdnumber.pro9
-rw-r--r--tests/auto/widgets/widgets/qlcdnumber/tst_qlcdnumber.cpp88
-rw-r--r--tests/auto/widgets/widgets/qlineedit/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qlineedit/qlineedit.pro5
-rw-r--r--tests/auto/widgets/widgets/qlineedit/testdata/frame/noFrame_Motif-32x96x96_win.pngbin0 -> 30154 bytes
-rw-r--r--tests/auto/widgets/widgets/qlineedit/testdata/frame/noFrame_Windows-32x96x96_win.pngbin0 -> 30154 bytes
-rw-r--r--tests/auto/widgets/widgets/qlineedit/testdata/frame/useFrame_Motif-32x96x96_win.pngbin0 -> 30154 bytes
-rw-r--r--tests/auto/widgets/widgets/qlineedit/testdata/frame/useFrame_Windows-32x96x96_win.pngbin0 -> 30154 bytes
-rw-r--r--tests/auto/widgets/widgets/qlineedit/testdata/setAlignment/auto_Motif-32x96x96_win.pngbin0 -> 30154 bytes
-rw-r--r--tests/auto/widgets/widgets/qlineedit/testdata/setAlignment/auto_Windows-32x96x96_win.pngbin0 -> 30154 bytes
-rw-r--r--tests/auto/widgets/widgets/qlineedit/testdata/setAlignment/hcenter_Motif-32x96x96_win.pngbin0 -> 30154 bytes
-rw-r--r--tests/auto/widgets/widgets/qlineedit/testdata/setAlignment/hcenter_Windows-32x96x96_win.pngbin0 -> 30154 bytes
-rw-r--r--tests/auto/widgets/widgets/qlineedit/testdata/setAlignment/left_Motif-32x96x96_win.pngbin0 -> 30154 bytes
-rw-r--r--tests/auto/widgets/widgets/qlineedit/testdata/setAlignment/left_Windows-32x96x96_win.pngbin0 -> 30154 bytes
-rw-r--r--tests/auto/widgets/widgets/qlineedit/testdata/setAlignment/right_Motif-32x96x96_win.pngbin0 -> 30154 bytes
-rw-r--r--tests/auto/widgets/widgets/qlineedit/testdata/setAlignment/right_Windows-32x96x96_win.pngbin0 -> 30154 bytes
-rw-r--r--tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp3835
-rw-r--r--tests/auto/widgets/widgets/qmainwindow/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qmainwindow/qmainwindow.pro3
-rw-r--r--tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp1742
-rw-r--r--tests/auto/widgets/widgets/qmdiarea/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qmdiarea/qmdiarea.pro14
-rw-r--r--tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp2773
-rw-r--r--tests/auto/widgets/widgets/qmdisubwindow/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qmdisubwindow/qmdisubwindow.pro8
-rw-r--r--tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp2032
-rw-r--r--tests/auto/widgets/widgets/qmenu/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qmenu/qmenu.pro5
-rw-r--r--tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp943
-rw-r--r--tests/auto/widgets/widgets/qmenubar/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qmenubar/qmenubar.pro3
-rw-r--r--tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp1291
-rw-r--r--tests/auto/widgets/widgets/qplaintextedit/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qplaintextedit/qplaintextedit.pro10
-rw-r--r--tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp1524
-rw-r--r--tests/auto/widgets/widgets/qprogressbar/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qprogressbar/qprogressbar.pro6
-rw-r--r--tests/auto/widgets/widgets/qprogressbar/tst_qprogressbar.cpp295
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/qpushbutton.pro6
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/testdata/setEnabled/disabled_Windows_win32_data0.qsnapbin0 -> 890 bytes
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/testdata/setEnabled/enabled_Motif_data0.qsnapbin0 -> 758 bytes
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/testdata/setEnabled/enabled_Windows_data0.qsnapbin0 -> 725 bytes
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/testdata/setEnabled/enabled_Windows_win32_data0.qsnapbin0 -> 735 bytes
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/testdata/setPixmap/Vpix_Motif_data0.qsnapbin0 -> 829 bytes
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/testdata/setPixmap/Vpix_Windows_data0.qsnapbin0 -> 796 bytes
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/testdata/setPixmap/Vpix_Windows_win32_data0.qsnapbin0 -> 796 bytes
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/testdata/setText/simple_Motif_data0.qsnapbin0 -> 742 bytes
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/testdata/setText/simple_Windows_data0.qsnapbin0 -> 709 bytes
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/testdata/setText/simple_Windows_win32_data0.qsnapbin0 -> 719 bytes
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp637
-rw-r--r--tests/auto/widgets/widgets/qradiobutton/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qradiobutton/qradiobutton.pro6
-rw-r--r--tests/auto/widgets/widgets/qradiobutton/tst_qradiobutton.cpp108
-rw-r--r--tests/auto/widgets/widgets/qregexpvalidator/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qregexpvalidator/qregexpvalidator.pro4
-rw-r--r--tests/auto/widgets/widgets/qregexpvalidator/tst_qregexpvalidator.cpp127
-rw-r--r--tests/auto/widgets/widgets/qscrollarea/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qscrollarea/qscrollarea.pro9
-rw-r--r--tests/auto/widgets/widgets/qscrollarea/tst_qscrollarea.cpp185
-rw-r--r--tests/auto/widgets/widgets/qscrollbar/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qscrollbar/qscrollbar.pro6
-rw-r--r--tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp147
-rw-r--r--tests/auto/widgets/widgets/qsizegrip/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qsizegrip/qsizegrip.pro6
-rw-r--r--tests/auto/widgets/widgets/qsizegrip/tst_qsizegrip.cpp201
-rw-r--r--tests/auto/widgets/widgets/qslider/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qslider/qslider.pro9
-rw-r--r--tests/auto/widgets/widgets/qslider/tst_qslider.cpp98
-rw-r--r--tests/auto/widgets/widgets/qspinbox/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qspinbox/qspinbox.pro3
-rw-r--r--tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp1049
-rw-r--r--tests/auto/widgets/widgets/qsplitter/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qsplitter/extradata.txt10067
-rw-r--r--tests/auto/widgets/widgets/qsplitter/qsplitter.pro12
-rw-r--r--tests/auto/widgets/widgets/qsplitter/setSizes3.dat2250
-rw-r--r--tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp777
-rw-r--r--tests/auto/widgets/widgets/qstackedwidget/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qstackedwidget/qstackedwidget.pro9
-rw-r--r--tests/auto/widgets/widgets/qstackedwidget/tst_qstackedwidget.cpp124
-rw-r--r--tests/auto/widgets/widgets/qstatusbar/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qstatusbar/qstatusbar.pro6
-rw-r--r--tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp279
-rw-r--r--tests/auto/widgets/widgets/qtabbar/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qtabbar/qtabbar.pro6
-rw-r--r--tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp655
-rw-r--r--tests/auto/widgets/widgets/qtabwidget/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qtabwidget/qtabwidget.pro12
-rw-r--r--tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp680
-rw-r--r--tests/auto/widgets/widgets/qtextbrowser/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qtextbrowser/anchor.html11
-rw-r--r--tests/auto/widgets/widgets/qtextbrowser/bigpage.html934
-rw-r--r--tests/auto/widgets/widgets/qtextbrowser/firstpage.html2
-rw-r--r--tests/auto/widgets/widgets/qtextbrowser/pagewithbg.html1
-rw-r--r--tests/auto/widgets/widgets/qtextbrowser/pagewithimage.html1
-rw-r--r--tests/auto/widgets/widgets/qtextbrowser/pagewithoutbg.html1
-rw-r--r--tests/auto/widgets/widgets/qtextbrowser/qtextbrowser.pro15
-rw-r--r--tests/auto/widgets/widgets/qtextbrowser/secondpage.html1
-rw-r--r--tests/auto/widgets/widgets/qtextbrowser/subdir/index.html1
-rw-r--r--tests/auto/widgets/widgets/qtextbrowser/thirdpage.html1
-rw-r--r--tests/auto/widgets/widgets/qtextbrowser/tst_qtextbrowser.cpp672
-rw-r--r--tests/auto/widgets/widgets/qtextedit/.gitignore2
-rw-r--r--tests/auto/widgets/widgets/qtextedit/fullWidthSelection/centered-fully-selected.pngbin0 -> 1232 bytes
-rw-r--r--tests/auto/widgets/widgets/qtextedit/fullWidthSelection/centered-partly-selected.pngbin0 -> 1231 bytes
-rw-r--r--tests/auto/widgets/widgets/qtextedit/fullWidthSelection/last-char-on-line.pngbin0 -> 1226 bytes
-rw-r--r--tests/auto/widgets/widgets/qtextedit/fullWidthSelection/last-char-on-parag.pngbin0 -> 1223 bytes
-rw-r--r--tests/auto/widgets/widgets/qtextedit/fullWidthSelection/multiple-full-width-lines.pngbin0 -> 1236 bytes
-rw-r--r--tests/auto/widgets/widgets/qtextedit/fullWidthSelection/nowrap_long.pngbin0 -> 1199 bytes
-rw-r--r--tests/auto/widgets/widgets/qtextedit/fullWidthSelection/single-full-width-line.pngbin0 -> 1225 bytes
-rw-r--r--tests/auto/widgets/widgets/qtextedit/qtextedit.pro18
-rw-r--r--tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp2391
-rw-r--r--tests/auto/widgets/widgets/qtoolbar/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qtoolbar/qtoolbar.pro7
-rw-r--r--tests/auto/widgets/widgets/qtoolbar/tst_qtoolbar.cpp1101
-rw-r--r--tests/auto/widgets/widgets/qtoolbox/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qtoolbox/qtoolbox.pro6
-rw-r--r--tests/auto/widgets/widgets/qtoolbox/tst_qtoolbox.cpp338
-rw-r--r--tests/auto/widgets/widgets/qtoolbutton/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qtoolbutton/qtoolbutton.pro3
-rw-r--r--tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp231
-rw-r--r--tests/auto/widgets/widgets/qworkspace/.gitignore1
-rw-r--r--tests/auto/widgets/widgets/qworkspace/qworkspace.pro3
-rw-r--r--tests/auto/widgets/widgets/qworkspace/tst_qworkspace.cpp679
-rw-r--r--tests/auto/widgets/widgets/widgets.pro57
582 files changed, 172546 insertions, 0 deletions
diff --git a/tests/auto/widgets/dialogs/dialogs.pro b/tests/auto/widgets/dialogs/dialogs.pro
new file mode 100644
index 0000000000..e74323a305
--- /dev/null
+++ b/tests/auto/widgets/dialogs/dialogs.pro
@@ -0,0 +1,18 @@
+TEMPLATE=subdirs
+SUBDIRS=\
+ qabstractprintdialog \
+ qcolordialog \
+ qdialog \
+ qerrormessage \
+ qfiledialog \
+ qfiledialog2 \
+ qfilesystemmodel \
+ qfontdialog \
+ qinputdialog \
+ qmessagebox \
+ qprogressdialog \
+ qsidebar \
+ qwizard \
+
+!contains(QT_CONFIG, private_tests): SUBDIRS -= \
+ qsidebar \
diff --git a/tests/auto/widgets/dialogs/qabstractprintdialog/.gitignore b/tests/auto/widgets/dialogs/qabstractprintdialog/.gitignore
new file mode 100644
index 0000000000..a768494da5
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qabstractprintdialog/.gitignore
@@ -0,0 +1 @@
+tst_qabstractprintdialog
diff --git a/tests/auto/widgets/dialogs/qabstractprintdialog/qabstractprintdialog.pro b/tests/auto/widgets/dialogs/qabstractprintdialog/qabstractprintdialog.pro
new file mode 100644
index 0000000000..fb72bbf7a9
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qabstractprintdialog/qabstractprintdialog.pro
@@ -0,0 +1,9 @@
+############################################################
+# Project file for autotest for file qabstractprintdialog.h
+############################################################
+
+load(qttest_p4)
+QT += widgets printsupport
+SOURCES += tst_qabstractprintdialog.cpp
+
+CONFIG += insignificant_test # QTBUG-21402
diff --git a/tests/auto/widgets/dialogs/qabstractprintdialog/tst_qabstractprintdialog.cpp b/tests/auto/widgets/dialogs/qabstractprintdialog/tst_qabstractprintdialog.cpp
new file mode 100644
index 0000000000..5d6165d174
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qabstractprintdialog/tst_qabstractprintdialog.cpp
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+#include <qcoreapplication.h>
+#include <qdebug.h>
+#include <qabstractprintdialog.h>
+#include <qprinter.h>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QAbstractPrintDialog : public QObject
+{
+Q_OBJECT
+
+#if defined(QT_NO_PRINTER) || defined(QT_NO_PRINTDIALOG)
+public slots:
+ void initTestCase();
+#else
+private slots:
+ void getSetCheck();
+ void setMinMax();
+ void setFromTo();
+#endif
+};
+
+#if defined(QT_NO_PRINTER) || defined(QT_NO_PRINTDIALOG)
+void tst_QAbstractPrintDialog::initTestCase()
+{
+ QSKIP("This test requires printing and print dialog support", SkipAll);
+}
+
+#else
+
+class MyAbstractPrintDialog : public QAbstractPrintDialog
+{
+public:
+ MyAbstractPrintDialog(QPrinter *p) : QAbstractPrintDialog(p) {}
+ int exec() { return 0; }
+};
+
+// Testing get/set functions
+void tst_QAbstractPrintDialog::getSetCheck()
+{
+ QPrinter printer;
+ MyAbstractPrintDialog obj1(&printer);
+ QCOMPARE(obj1.printer(), &printer);
+ // PrintDialogOptions QAbstractPrintDialog::enabledOptions()
+ // void QAbstractPrintDialog::setEnabledOptions(PrintDialogOptions)
+ obj1.setEnabledOptions(QAbstractPrintDialog::PrintDialogOptions(QAbstractPrintDialog::None));
+ QCOMPARE(QAbstractPrintDialog::PrintDialogOptions(QAbstractPrintDialog::None), obj1.enabledOptions());
+ obj1.setEnabledOptions(QAbstractPrintDialog::PrintDialogOptions(QAbstractPrintDialog::PrintToFile));
+ QCOMPARE(QAbstractPrintDialog::PrintDialogOptions(QAbstractPrintDialog::PrintToFile), obj1.enabledOptions());
+ obj1.setEnabledOptions(QAbstractPrintDialog::PrintDialogOptions(QAbstractPrintDialog::PrintSelection));
+ QCOMPARE(QAbstractPrintDialog::PrintDialogOptions(QAbstractPrintDialog::PrintSelection), obj1.enabledOptions());
+ obj1.setEnabledOptions(QAbstractPrintDialog::PrintDialogOptions(QAbstractPrintDialog::PrintPageRange));
+ QCOMPARE(QAbstractPrintDialog::PrintDialogOptions(QAbstractPrintDialog::PrintPageRange), obj1.enabledOptions());
+ obj1.setEnabledOptions(QAbstractPrintDialog::PrintDialogOptions(QAbstractPrintDialog::PrintCollateCopies));
+ QCOMPARE(QAbstractPrintDialog::PrintDialogOptions(QAbstractPrintDialog::PrintCollateCopies), obj1.enabledOptions());
+
+ // PrintRange QAbstractPrintDialog::printRange()
+ // void QAbstractPrintDialog::setPrintRange(PrintRange)
+ obj1.setPrintRange(QAbstractPrintDialog::PrintRange(QAbstractPrintDialog::AllPages));
+ QCOMPARE(QAbstractPrintDialog::PrintRange(QAbstractPrintDialog::AllPages), obj1.printRange());
+ obj1.setPrintRange(QAbstractPrintDialog::PrintRange(QAbstractPrintDialog::Selection));
+ QCOMPARE(QAbstractPrintDialog::PrintRange(QAbstractPrintDialog::Selection), obj1.printRange());
+ obj1.setPrintRange(QAbstractPrintDialog::PrintRange(QAbstractPrintDialog::PageRange));
+ QCOMPARE(QAbstractPrintDialog::PrintRange(QAbstractPrintDialog::PageRange), obj1.printRange());
+}
+
+void tst_QAbstractPrintDialog::setMinMax()
+{
+ QPrinter printer;
+ MyAbstractPrintDialog obj1(&printer);
+ obj1.setEnabledOptions(QAbstractPrintDialog::PrintDialogOptions(QAbstractPrintDialog::None));
+ QCOMPARE(obj1.minPage(), 1);
+ QCOMPARE(obj1.maxPage(), INT_MAX);
+ QVERIFY(!obj1.isOptionEnabled(QAbstractPrintDialog::PrintPageRange));
+ obj1.setMinMax(2,5);
+ QCOMPARE(obj1.minPage(), 2);
+ QCOMPARE(obj1.maxPage(), 5);
+ QVERIFY(obj1.enabledOptions() & QAbstractPrintDialog::PrintPageRange);
+ QVERIFY(obj1.isOptionEnabled(QAbstractPrintDialog::PrintPageRange));
+}
+
+void tst_QAbstractPrintDialog::setFromTo()
+{
+ QPrinter printer;
+ MyAbstractPrintDialog obj1(&printer);
+ QCOMPARE(obj1.fromPage(), 0);
+ QCOMPARE(obj1.toPage(), 0);
+ obj1.setMinMax(0,0);
+ QCOMPARE(obj1.minPage(), 0);
+ QCOMPARE(obj1.maxPage(), 0);
+ obj1.setFromTo(20,50);
+ QCOMPARE(obj1.fromPage(), 20);
+ QCOMPARE(obj1.toPage(), 50);
+ QCOMPARE(obj1.minPage(), 1);
+ QCOMPARE(obj1.maxPage(), 50);
+}
+
+#endif
+
+QTEST_MAIN(tst_QAbstractPrintDialog)
+#include "tst_qabstractprintdialog.moc"
diff --git a/tests/auto/widgets/dialogs/qcolordialog/.gitignore b/tests/auto/widgets/dialogs/qcolordialog/.gitignore
new file mode 100644
index 0000000000..b7a8ebd8f8
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qcolordialog/.gitignore
@@ -0,0 +1 @@
+tst_qcolordialog
diff --git a/tests/auto/widgets/dialogs/qcolordialog/qcolordialog.pro b/tests/auto/widgets/dialogs/qcolordialog/qcolordialog.pro
new file mode 100644
index 0000000000..4f195dac2b
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qcolordialog/qcolordialog.pro
@@ -0,0 +1,6 @@
+load(qttest_p4)
+QT += widgets
+SOURCES += tst_qcolordialog.cpp
+
+
+
diff --git a/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp b/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp
new file mode 100644
index 0000000000..3ae1e63a8e
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include <QtGui/QtGui>
+#include <QtWidgets/QColorDialog>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+QT_FORWARD_DECLARE_CLASS(QtTestEventThread)
+
+class tst_QColorDialog : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QColorDialog();
+ virtual ~tst_QColorDialog();
+
+#ifndef Q_WS_MAC
+public slots:
+ void postKeyReturn();
+private slots:
+ void defaultOkButton();
+#endif
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+ void init();
+ void cleanup();
+
+private slots:
+ void native_activeModalWidget();
+ void task247349_alpha();
+};
+
+class TestNativeDialog : public QColorDialog
+{
+ Q_OBJECT
+public:
+ QWidget *m_activeModalWidget;
+
+ TestNativeDialog(QWidget *parent = 0)
+ : QColorDialog(parent), m_activeModalWidget(0)
+ {
+ QTimer::singleShot(1, this, SLOT(test_activeModalWidgetSignal()));
+ }
+
+public slots:
+ void test_activeModalWidgetSignal()
+ {
+ m_activeModalWidget = qApp->activeModalWidget();
+ }
+};
+
+tst_QColorDialog::tst_QColorDialog()
+{
+}
+
+tst_QColorDialog::~tst_QColorDialog()
+{
+}
+
+void tst_QColorDialog::native_activeModalWidget()
+{
+ // Check that QApplication::activeModalWidget retruns the
+ // color dialog when it is executing, even when using a native
+ // dialog:
+ TestNativeDialog d;
+ QTimer::singleShot(1000, &d, SLOT(hide()));
+ d.exec();
+ QVERIFY(&d == d.m_activeModalWidget);
+}
+
+void tst_QColorDialog::initTestCase()
+{
+}
+
+void tst_QColorDialog::cleanupTestCase()
+{
+}
+
+void tst_QColorDialog::init()
+{
+}
+
+void tst_QColorDialog::cleanup()
+{
+}
+
+#ifndef Q_WS_MAC
+//copied from QFontDialogTest
+void tst_QColorDialog::postKeyReturn() {
+ QWidgetList list = QApplication::topLevelWidgets();
+ for (int i=0; i<list.count(); ++i) {
+ QColorDialog *dialog = qobject_cast<QColorDialog *>(list[i]);
+ if (dialog) {
+ QTest::keyClick( list[i], Qt::Key_Return, Qt::NoModifier );
+ return;
+ }
+ }
+}
+
+void tst_QColorDialog::defaultOkButton()
+{
+ bool ok = false;
+ QTimer::singleShot(500, this, SLOT(postKeyReturn()));
+ QColorDialog::getRgba(0xffffffff, &ok);
+ QVERIFY(ok);
+}
+#endif
+
+void tst_QColorDialog::task247349_alpha()
+{
+ QColorDialog dialog;
+ dialog.setOption(QColorDialog::ShowAlphaChannel, true);
+ int alpha = 0x17;
+ dialog.setCurrentColor(QColor(0x01, 0x02, 0x03, alpha));
+ QCOMPARE(alpha, dialog.currentColor().alpha());
+ QCOMPARE(alpha, qAlpha(dialog.currentColor().rgba()));
+}
+
+QTEST_MAIN(tst_QColorDialog)
+#include "tst_qcolordialog.moc"
diff --git a/tests/auto/widgets/dialogs/qdialog/.gitignore b/tests/auto/widgets/dialogs/qdialog/.gitignore
new file mode 100644
index 0000000000..4a4b5ebcbe
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qdialog/.gitignore
@@ -0,0 +1 @@
+tst_qdialog
diff --git a/tests/auto/widgets/dialogs/qdialog/qdialog.pro b/tests/auto/widgets/dialogs/qdialog/qdialog.pro
new file mode 100644
index 0000000000..a3596b60f6
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qdialog/qdialog.pro
@@ -0,0 +1,5 @@
+load(qttest_p4)
+QT += widgets
+SOURCES += tst_qdialog.cpp
+
+CONFIG += insignificant_test # QTBUG-21402
diff --git a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp
new file mode 100644
index 0000000000..0f4acdcc9e
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp
@@ -0,0 +1,609 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+#include <qdialog.h>
+#include <qapplication.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qstyle.h>
+#include <QVBoxLayout>
+#include <QSizeGrip>
+
+Q_DECLARE_METATYPE(QSize)
+
+
+QT_FORWARD_DECLARE_CLASS(QDialog)
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QDialog : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QDialog();
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+private slots:
+ void getSetCheck();
+ void showExtension_data();
+ void showExtension();
+ void defaultButtons();
+ void showMaximized();
+ void showMinimized();
+ void showFullScreen();
+#if !defined(Q_WS_X11) && !defined(Q_OS_WINCE)
+ void showAsTool();
+#endif
+#ifndef Q_OS_WINCE
+ void toolDialogPosition();
+#endif
+ void deleteMainDefault();
+ void deleteInExec();
+#if !defined(QT_NO_EXCEPTIONS) && !defined(Q_OS_MAC) && !(defined(Q_OS_WINCE) && defined(_ARM_))
+ void throwInExec();
+#endif
+ void showSizeGrip();
+ void setVisible();
+ void reject();
+
+private:
+ QDialog *testWidget;
+};
+
+// Testing get/set functions
+void tst_QDialog::getSetCheck()
+{
+ QDialog obj1;
+ // QWidget* QDialog::extension()
+ // void QDialog::setExtension(QWidget*)
+ QWidget *var1 = new QWidget;
+ obj1.setExtension(var1);
+ QCOMPARE(var1, obj1.extension());
+ obj1.setExtension((QWidget *)0);
+ QCOMPARE((QWidget *)0, obj1.extension());
+ // No delete var1, since setExtension takes ownership
+
+ // int QDialog::result()
+ // void QDialog::setResult(int)
+ obj1.setResult(0);
+ QCOMPARE(0, obj1.result());
+ obj1.setResult(INT_MIN);
+ QCOMPARE(INT_MIN, obj1.result());
+ obj1.setResult(INT_MAX);
+ QCOMPARE(INT_MAX, obj1.result());
+}
+
+// work around function being protected
+class DummyDialog : public QDialog {
+public:
+ DummyDialog(): QDialog(0) {}
+ void showExtension( bool b ) { QDialog::showExtension( b ); }
+};
+
+class ToolDialog : public QDialog
+{
+public:
+ ToolDialog(QWidget *parent = 0) : QDialog(parent, Qt::Tool), mWasActive(false), tId(-1) {
+ }
+ bool wasActive() const { return mWasActive; }
+
+ int exec() {
+ tId = startTimer(300);
+ return QDialog::exec();
+ }
+protected:
+ void timerEvent(QTimerEvent *event) {
+ if (tId == event->timerId()) {
+ killTimer(tId);
+ mWasActive = isActiveWindow();
+ reject();
+ }
+ }
+
+private:
+ int mWasActive;
+ int tId;
+};
+
+tst_QDialog::tst_QDialog()
+
+{
+}
+
+void tst_QDialog::initTestCase()
+{
+ // Create the test class
+ testWidget = new QDialog(0, Qt::X11BypassWindowManagerHint);
+ testWidget->resize(200,200);
+ testWidget->show();
+ qApp->setActiveWindow(testWidget);
+}
+
+void tst_QDialog::cleanupTestCase()
+{
+ if (testWidget) {
+ delete testWidget;
+ testWidget = 0;
+ }
+}
+
+void tst_QDialog::showExtension_data()
+{
+ QTest::addColumn<QSize>("dlgSize");
+ QTest::addColumn<QSize>("extSize");
+ QTest::addColumn<bool>("horizontal");
+ QTest::addColumn<QSize>("result");
+
+ //next we fill it with data
+ QTest::newRow( "data0" ) << QSize(100,100) << QSize(50,50) << (bool)FALSE << QSize(100,150);
+ QTest::newRow( "data1" ) << QSize(100,100) << QSize(120,50) << (bool)FALSE << QSize(120,150);
+ QTest::newRow( "data2" ) << QSize(100,100) << QSize(50,50) << (bool)TRUE << QSize(150,100);
+ QTest::newRow( "data3" ) << QSize(100,100) << QSize(50,120) << (bool)TRUE << QSize(150,120);
+}
+
+void tst_QDialog::showExtension()
+{
+ QFETCH( QSize, dlgSize );
+ QFETCH( QSize, extSize );
+ QFETCH( bool, horizontal );
+
+ // set geometry of main dialog and extension widget
+ testWidget->setFixedSize( dlgSize );
+ QWidget *ext = new QWidget( testWidget );
+ ext->setFixedSize( extSize );
+ testWidget->setExtension( ext );
+ testWidget->setOrientation( horizontal ? Qt::Horizontal : Qt::Vertical );
+
+ QCOMPARE( testWidget->size(), dlgSize );
+ QPoint oldPosition = testWidget->pos();
+
+ // show
+ ((DummyDialog*)testWidget)->showExtension( TRUE );
+// while ( testWidget->size() == dlgSize )
+// qApp->processEvents();
+
+ QTEST( testWidget->size(), "result" );
+
+ QCOMPARE(testWidget->pos(), oldPosition);
+
+ // hide extension. back to old size ?
+ ((DummyDialog*)testWidget)->showExtension( FALSE );
+ QCOMPARE( testWidget->size(), dlgSize );
+
+ testWidget->setExtension( 0 );
+}
+
+void tst_QDialog::defaultButtons()
+{
+ QLineEdit *lineEdit = new QLineEdit(testWidget);
+ QPushButton *push = new QPushButton("Button 1", testWidget);
+ QPushButton *pushTwo = new QPushButton("Button 2", testWidget);
+ QPushButton *pushThree = new QPushButton("Button 3", testWidget);
+ pushThree->setAutoDefault(FALSE);
+
+ //we need to show the buttons. Otherwise they won't get the focus
+ push->show();
+ pushTwo->show();
+ pushThree->show();
+
+ push->setDefault(TRUE);
+ QVERIFY(push->isDefault());
+
+ pushTwo->setFocus();
+ QVERIFY(pushTwo->isDefault());
+ pushThree->setFocus();
+ QVERIFY(push->isDefault());
+ lineEdit->setFocus();
+ QVERIFY(push->isDefault());
+
+ pushTwo->setDefault(TRUE);
+ QVERIFY(pushTwo->isDefault());
+
+ pushTwo->setFocus();
+ QVERIFY(pushTwo->isDefault());
+ lineEdit->setFocus();
+ QVERIFY(pushTwo->isDefault());
+}
+
+void tst_QDialog::showMaximized()
+{
+ QDialog dialog(0);
+ dialog.setSizeGripEnabled(true);
+ QSizeGrip *sizeGrip = qFindChild<QSizeGrip *>(&dialog);
+ QVERIFY(sizeGrip);
+
+ dialog.showMaximized();
+ QVERIFY(dialog.isMaximized());
+ QVERIFY(dialog.isVisible());
+#if !defined(Q_OS_MAC) && !defined(Q_OS_IRIX) && !defined(Q_OS_HPUX)
+ QVERIFY(!sizeGrip->isVisible());
+#endif
+
+ dialog.showNormal();
+ QVERIFY(!dialog.isMaximized());
+ QVERIFY(dialog.isVisible());
+ QVERIFY(sizeGrip->isVisible());
+
+ dialog.showMaximized();
+ QVERIFY(dialog.isMaximized());
+ QVERIFY(dialog.isVisible());
+
+ dialog.hide();
+ QVERIFY(dialog.isMaximized());
+ QVERIFY(!dialog.isVisible());
+
+ dialog.show();
+ QVERIFY(dialog.isMaximized());
+ QVERIFY(dialog.isVisible());
+
+ dialog.hide();
+ QVERIFY(dialog.isMaximized());
+ QVERIFY(!dialog.isVisible());
+
+ dialog.showMaximized();
+ QVERIFY(dialog.isMaximized());
+ QVERIFY(dialog.isVisible());
+}
+
+void tst_QDialog::showMinimized()
+{
+ QDialog dialog(0);
+
+ dialog.showMinimized();
+ QVERIFY(dialog.isMinimized());
+ QVERIFY(dialog.isVisible());
+
+ dialog.showNormal();
+ QVERIFY(!dialog.isMinimized());
+ QVERIFY(dialog.isVisible());
+
+ dialog.showMinimized();
+ QVERIFY(dialog.isMinimized());
+ QVERIFY(dialog.isVisible());
+
+ dialog.hide();
+ QVERIFY(dialog.isMinimized());
+ QVERIFY(!dialog.isVisible());
+
+ dialog.show();
+ QVERIFY(dialog.isMinimized());
+ QVERIFY(dialog.isVisible());
+
+ dialog.hide();
+ QVERIFY(dialog.isMinimized());
+ QVERIFY(!dialog.isVisible());
+
+ dialog.showMinimized();
+ QVERIFY(dialog.isMinimized());
+ QVERIFY(dialog.isVisible());
+}
+
+void tst_QDialog::showFullScreen()
+{
+ QDialog dialog(0, Qt::X11BypassWindowManagerHint);
+ dialog.setSizeGripEnabled(true);
+ QSizeGrip *sizeGrip = qFindChild<QSizeGrip *>(&dialog);
+ QVERIFY(sizeGrip);
+
+ qApp->syncX();
+ dialog.showFullScreen();
+ QVERIFY(dialog.isFullScreen());
+ QVERIFY(dialog.isVisible());
+ QVERIFY(!sizeGrip->isVisible());
+
+ qApp->syncX();
+ dialog.showNormal();
+ QVERIFY(!dialog.isFullScreen());
+ QVERIFY(dialog.isVisible());
+ QVERIFY(sizeGrip->isVisible());
+
+ qApp->syncX();
+ dialog.showFullScreen();
+ QVERIFY(dialog.isFullScreen());
+ QVERIFY(dialog.isVisible());
+
+ qApp->syncX();
+ dialog.hide();
+ QVERIFY(dialog.isFullScreen());
+ QVERIFY(!dialog.isVisible());
+
+ qApp->syncX();
+ dialog.show();
+ QVERIFY(dialog.isFullScreen());
+ QVERIFY(dialog.isVisible());
+
+ qApp->syncX();
+ dialog.hide();
+ QVERIFY(dialog.isFullScreen());
+ QVERIFY(!dialog.isVisible());
+
+ qApp->syncX();
+ dialog.showFullScreen();
+ QVERIFY(dialog.isFullScreen());
+ QVERIFY(dialog.isVisible());
+
+ qApp->syncX();
+ dialog.hide();
+ QVERIFY(dialog.isFullScreen());
+ QVERIFY(!dialog.isVisible());
+}
+
+// Qt/X11: Skipped since activeWindow() is not respected by all window managers.
+// Qt/WinCE: No real support for Qt::Tool on WinCE.
+#if !defined(Q_WS_X11) && !defined(Q_OS_WINCE)
+void tst_QDialog::showAsTool()
+{
+ ToolDialog dialog(testWidget);
+ testWidget->activateWindow();
+ dialog.exec();
+ QTest::qWait(100);
+ if (testWidget->style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, testWidget)) {
+ QCOMPARE(dialog.wasActive(), true);
+ } else {
+ QCOMPARE(dialog.wasActive(), false);
+ }
+}
+#endif
+
+// Verify that pos() returns the same before and after show()
+// for a dialog with the Tool window type.
+// No real support for Qt::Tool on WinCE, so skip this test.
+#ifndef Q_OS_WINCE
+void tst_QDialog::toolDialogPosition()
+{
+ QDialog dialog(0, Qt::Tool);
+ dialog.move(QPoint(100,100));
+ const QPoint beforeShowPosition = dialog.pos();
+ dialog.show();
+ const QPoint afterShowPosition = dialog.pos();
+ QCOMPARE(afterShowPosition, beforeShowPosition);
+}
+#endif
+
+class Dialog : public QDialog
+{
+public:
+ Dialog(QPushButton *&button)
+ {
+ button = new QPushButton(this);
+ }
+};
+
+void tst_QDialog::deleteMainDefault()
+{
+ QPushButton *button;
+ Dialog dialog(button);
+ button->setDefault(true);
+ delete button;
+ dialog.show();
+ QTestEventLoop::instance().enterLoop(2);
+}
+
+void tst_QDialog::deleteInExec()
+{
+ QDialog *dialog = new QDialog(0);
+ QMetaObject::invokeMethod(dialog, "deleteLater", Qt::QueuedConnection);
+ QCOMPARE(dialog->exec(), int(QDialog::Rejected));
+}
+
+// Throwing exceptions in exec() is not supported on Mac or on WinCE/ARM.
+#if !defined(QT_NO_EXCEPTIONS) && !defined(Q_OS_MAC) && !(defined(Q_OS_WINCE) && defined(_ARM_))
+class QDialogTestException : public std::exception { };
+
+class ExceptionDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ ExceptionDialog() : QDialog(0) { }
+public slots:
+ void throwException()
+ {
+ QDialogTestException e;
+ throw e;
+ }
+};
+
+void tst_QDialog::throwInExec()
+{
+#if defined(Q_OS_LINUX)
+ // C++ exceptions can't be passed through glib callbacks. Skip the test if
+ // we're using the glib event loop.
+ QByteArray dispatcher = QAbstractEventDispatcher::instance()->metaObject()->className();
+ if (dispatcher.contains("Glib")) {
+ QSKIP(
+ qPrintable(QString(
+ "Throwing exceptions in exec() won't work if %1 event dispatcher is used.\n"
+ "Try running with QT_NO_GLIB=1 in environment."
+ ).arg(QString::fromLatin1(dispatcher))),
+ SkipAll
+ );
+ }
+#endif
+
+ int caughtExceptions = 0;
+ try {
+ ExceptionDialog dialog;
+ QMetaObject::invokeMethod(&dialog, "throwException", Qt::QueuedConnection);
+ QMetaObject::invokeMethod(&dialog, "reject", Qt::QueuedConnection);
+ (void) dialog.exec();
+ } catch(...) {
+ ++caughtExceptions;
+ }
+ QCOMPARE(caughtExceptions, 1);
+}
+#endif
+
+// From Task 124269
+void tst_QDialog::showSizeGrip()
+{
+#ifndef QT_NO_SIZEGRIP
+ QDialog dialog(0);
+ dialog.show();
+ QWidget *ext = new QWidget(&dialog);
+ QVERIFY(!dialog.extension());
+ QVERIFY(!dialog.isSizeGripEnabled());
+
+ dialog.setSizeGripEnabled(true);
+ QPointer<QSizeGrip> sizeGrip = qFindChild<QSizeGrip *>(&dialog);
+ QVERIFY(sizeGrip);
+ QVERIFY(sizeGrip->isVisible());
+ QVERIFY(dialog.isSizeGripEnabled());
+
+ dialog.setExtension(ext);
+ QVERIFY(dialog.extension() && !dialog.extension()->isVisible());
+ QVERIFY(dialog.isSizeGripEnabled());
+
+ // normal show/hide sequence
+ dialog.showExtension(true);
+ QVERIFY(dialog.extension() && dialog.extension()->isVisible());
+ QVERIFY(!dialog.isSizeGripEnabled());
+ QVERIFY(!sizeGrip);
+
+ dialog.showExtension(false);
+ QVERIFY(dialog.extension() && !dialog.extension()->isVisible());
+ QVERIFY(dialog.isSizeGripEnabled());
+ sizeGrip = qFindChild<QSizeGrip *>(&dialog);
+ QVERIFY(sizeGrip);
+ QVERIFY(sizeGrip->isVisible());
+
+ // show/hide sequence with interleaved size grip update
+ dialog.showExtension(true);
+ QVERIFY(dialog.extension() && dialog.extension()->isVisible());
+ QVERIFY(!dialog.isSizeGripEnabled());
+ QVERIFY(!sizeGrip);
+
+ dialog.setSizeGripEnabled(false);
+ QVERIFY(!dialog.isSizeGripEnabled());
+
+ dialog.showExtension(false);
+ QVERIFY(dialog.extension() && !dialog.extension()->isVisible());
+ QVERIFY(!dialog.isSizeGripEnabled());
+
+ dialog.setSizeGripEnabled(true);
+ sizeGrip = qFindChild<QSizeGrip *>(&dialog);
+ QVERIFY(sizeGrip);
+ QVERIFY(sizeGrip->isVisible());
+ sizeGrip->hide();
+ dialog.hide();
+ dialog.show();
+ QVERIFY(!sizeGrip->isVisible());
+#endif
+}
+
+void tst_QDialog::setVisible()
+{
+ QWidget topLevel;
+ topLevel.show();
+
+ QDialog *dialog = new QDialog;
+ dialog->setLayout(new QVBoxLayout);
+ dialog->layout()->addWidget(new QPushButton("dialog button"));
+
+ QWidget *widget = new QWidget(&topLevel);
+ widget->setLayout(new QVBoxLayout);
+ widget->layout()->addWidget(dialog);
+
+ QVERIFY(!dialog->isVisible());
+ QVERIFY(!dialog->isHidden());
+
+ widget->show();
+ QVERIFY(dialog->isVisible());
+ QVERIFY(!dialog->isHidden());
+
+ widget->hide();
+ dialog->hide();
+ widget->show();
+ QVERIFY(!dialog->isVisible());
+ QVERIFY(dialog->isHidden());
+}
+
+class TestRejectDialog : public QDialog
+{
+ public:
+ TestRejectDialog() : cancelReject(false), called(0) {}
+ void reject()
+ {
+ called++;
+ if (!cancelReject)
+ QDialog::reject();
+ }
+ bool cancelReject;
+ int called;
+};
+
+void tst_QDialog::reject()
+{
+ TestRejectDialog dialog;
+ dialog.show();
+ QTest::qWaitForWindowShown(&dialog);
+ QTRY_VERIFY(dialog.isVisible());
+ dialog.reject();
+ QTRY_VERIFY(!dialog.isVisible());
+ QCOMPARE(dialog.called, 1);
+
+ dialog.show();
+ QTest::qWaitForWindowShown(&dialog);
+ QTRY_VERIFY(dialog.isVisible());
+ QVERIFY(dialog.close());
+ QTRY_VERIFY(!dialog.isVisible());
+ QCOMPARE(dialog.called, 2);
+
+ dialog.cancelReject = true;
+ dialog.show();
+ QTest::qWaitForWindowShown(&dialog);
+ QTRY_VERIFY(dialog.isVisible());
+ dialog.reject();
+ QTRY_VERIFY(dialog.isVisible());
+ QCOMPARE(dialog.called, 3);
+ QVERIFY(!dialog.close());
+ QTRY_VERIFY(dialog.isVisible());
+ QCOMPARE(dialog.called, 4);
+}
+
+
+QTEST_MAIN(tst_QDialog)
+#include "tst_qdialog.moc"
diff --git a/tests/auto/widgets/dialogs/qerrormessage/.gitignore b/tests/auto/widgets/dialogs/qerrormessage/.gitignore
new file mode 100644
index 0000000000..1bb653fb72
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qerrormessage/.gitignore
@@ -0,0 +1 @@
+tst_qerrormessage
diff --git a/tests/auto/widgets/dialogs/qerrormessage/qerrormessage.pro b/tests/auto/widgets/dialogs/qerrormessage/qerrormessage.pro
new file mode 100644
index 0000000000..363d085cbf
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qerrormessage/qerrormessage.pro
@@ -0,0 +1,10 @@
+load(qttest_p4)
+TEMPLATE = app
+TARGET = tst_qerrormessage
+DEPENDPATH += .
+INCLUDEPATH += .
+
+QT += widgets
+
+# Input
+SOURCES += tst_qerrormessage.cpp
diff --git a/tests/auto/widgets/dialogs/qerrormessage/tst_qerrormessage.cpp b/tests/auto/widgets/dialogs/qerrormessage/tst_qerrormessage.cpp
new file mode 100644
index 0000000000..d3ee640b1a
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qerrormessage/tst_qerrormessage.cpp
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtTest/QtTest>
+#include <QErrorMessage>
+#include <QDebug>
+#include <QCheckBox>
+
+class tst_QErrorMessage : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void dontShowAgain();
+ void dontShowCategoryAgain();
+
+};
+
+void tst_QErrorMessage::dontShowAgain()
+{
+ QString plainString = QLatin1String("foo");
+ QString htmlString = QLatin1String("foo<br>bar");
+ QCheckBox *checkBox = 0;
+
+ QErrorMessage errorMessageDialog(0);
+
+ // show an error with plain string
+ errorMessageDialog.showMessage(plainString);
+ QVERIFY(errorMessageDialog.isVisible());
+ checkBox = qFindChild<QCheckBox*>(&errorMessageDialog);
+ QVERIFY(checkBox);
+ QVERIFY(checkBox->isChecked());
+ errorMessageDialog.close();
+
+ errorMessageDialog.showMessage(plainString);
+ QVERIFY(errorMessageDialog.isVisible());
+ checkBox = qFindChild<QCheckBox*>(&errorMessageDialog);
+ QVERIFY(checkBox);
+ QVERIFY(checkBox->isChecked());
+ checkBox->setChecked(false);
+ errorMessageDialog.close();
+
+ errorMessageDialog.showMessage(plainString);
+ QVERIFY(!errorMessageDialog.isVisible());
+
+ // show an error with an html string
+ errorMessageDialog.showMessage(htmlString);
+ QVERIFY(errorMessageDialog.isVisible());
+ checkBox = qFindChild<QCheckBox*>(&errorMessageDialog);
+ QVERIFY(checkBox);
+ QVERIFY(!checkBox->isChecked());
+ checkBox->setChecked(true);
+ errorMessageDialog.close();
+
+ errorMessageDialog.showMessage(htmlString);
+ QVERIFY(errorMessageDialog.isVisible());
+ checkBox = qFindChild<QCheckBox*>(&errorMessageDialog);
+ QVERIFY(checkBox);
+ QVERIFY(checkBox->isChecked());
+ checkBox->setChecked(false);
+ errorMessageDialog.close();
+
+ errorMessageDialog.showMessage(htmlString);
+ QVERIFY(!errorMessageDialog.isVisible());
+}
+
+void tst_QErrorMessage::dontShowCategoryAgain()
+{
+ QString htmlString = QLatin1String("foo<br>bar");
+ QString htmlString2 = QLatin1String("foo2<br>bar2");
+ QCheckBox *checkBox = 0;
+
+ QErrorMessage errorMessageDialog(0);
+
+ errorMessageDialog.showMessage(htmlString,"Cat 1");
+ QVERIFY(errorMessageDialog.isVisible());
+ checkBox = qFindChild<QCheckBox*>(&errorMessageDialog);
+ QVERIFY(checkBox);
+ QVERIFY(checkBox->isChecked());
+ checkBox->setChecked(true);
+ errorMessageDialog.close();
+
+ errorMessageDialog.showMessage(htmlString,"Cat 1");
+ QVERIFY(errorMessageDialog.isVisible());
+ checkBox = qFindChild<QCheckBox*>(&errorMessageDialog);
+ QVERIFY(checkBox);
+ QVERIFY(checkBox->isChecked());
+ checkBox->setChecked(true);
+ errorMessageDialog.close();
+
+ errorMessageDialog.showMessage(htmlString2,"Cat 1");
+ QVERIFY(errorMessageDialog.isVisible());
+ checkBox = qFindChild<QCheckBox*>(&errorMessageDialog);
+ QVERIFY(checkBox);
+ QVERIFY(checkBox->isChecked());
+ checkBox->setChecked(true);
+ errorMessageDialog.close();
+
+ errorMessageDialog.showMessage(htmlString,"Cat 1");
+ QVERIFY(errorMessageDialog.isVisible());
+ checkBox = qFindChild<QCheckBox*>(&errorMessageDialog);
+ QVERIFY(checkBox);
+ QVERIFY(checkBox->isChecked());
+ checkBox->setChecked(false);
+ errorMessageDialog.close();
+
+ errorMessageDialog.showMessage(htmlString2,"Cat 1");
+ QVERIFY(!errorMessageDialog.isVisible());
+
+ errorMessageDialog.showMessage(htmlString,"Cat 1");
+ QVERIFY(!errorMessageDialog.isVisible());
+
+ errorMessageDialog.showMessage(htmlString);
+ QVERIFY(errorMessageDialog.isVisible());
+
+ errorMessageDialog.showMessage(htmlString,"Cat 2");
+ QVERIFY(errorMessageDialog.isVisible());
+}
+
+QTEST_MAIN(tst_QErrorMessage)
+#include "tst_qerrormessage.moc"
diff --git a/tests/auto/widgets/dialogs/qfiledialog/.gitignore b/tests/auto/widgets/dialogs/qfiledialog/.gitignore
new file mode 100644
index 0000000000..a696596ee9
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfiledialog/.gitignore
@@ -0,0 +1 @@
+tst_qfiledialog
diff --git a/tests/auto/widgets/dialogs/qfiledialog/qfiledialog.pro b/tests/auto/widgets/dialogs/qfiledialog/qfiledialog.pro
new file mode 100644
index 0000000000..92fba98796
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfiledialog/qfiledialog.pro
@@ -0,0 +1,23 @@
+############################################################
+# Project file for autotest for file qfiledialog.h
+############################################################
+
+load(qttest_p4)
+QT += widgets widgets-private
+QT += core-private gui-private
+SOURCES += tst_qfiledialog.cpp
+
+wince* {
+ addFiles.files = *.cpp
+ addFiles.path = .
+ filesInDir.files = *.pro
+ filesInDir.path = someDir
+ DEPLOYMENT += addFiles filesInDir
+}
+
+wince* {
+ DEFINES += SRCDIR=\\\"./\\\"
+} else {
+ DEFINES += SRCDIR=\\\"$$PWD/\\\"
+}
+
diff --git a/tests/auto/widgets/dialogs/qfiledialog/resources/file.txt b/tests/auto/widgets/dialogs/qfiledialog/resources/file.txt
new file mode 100644
index 0000000000..8a03e0e55f
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfiledialog/resources/file.txt
@@ -0,0 +1 @@
+This is a simple text file.
diff --git a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp
new file mode 100644
index 0000000000..9abcd407d0
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp
@@ -0,0 +1,1349 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+#include <qcoreapplication.h>
+#include <qdebug.h>
+#include <qfiledialog.h>
+#include <qabstractitemdelegate.h>
+#include <qdirmodel.h>
+#include <qitemdelegate.h>
+#include <qlistview.h>
+#include <qcombobox.h>
+#include <qpushbutton.h>
+#include <qtoolbutton.h>
+#include <qtreeview.h>
+#include <qheaderview.h>
+#include <qcompleter.h>
+#include <qaction.h>
+#include <qdialogbuttonbox.h>
+#include <qsortfilterproxymodel.h>
+#include <qlineedit.h>
+#include <qlayout.h>
+#if defined QT_BUILD_INTERNAL
+#include "../../../src/widgets/dialogs/qsidebar_p.h"
+#include "../../../src/widgets/dialogs/qfilesystemmodel_p.h"
+#include "../../../src/widgets/dialogs/qfiledialog_p.h"
+#endif
+#include <QFileDialog>
+#include <QFileSystemModel>
+
+#include "../../../network-settings.h"
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+#if defined(Q_OS_UNIX)
+#ifdef QT_BUILD_INTERNAL
+QT_BEGIN_NAMESPACE
+extern Q_GUI_EXPORT QString qt_tildeExpansion(const QString &path, bool *expanded = 0);
+QT_END_NAMESPACE
+#endif
+#endif
+
+class QNonNativeFileDialog : public QFileDialog
+{
+ Q_OBJECT
+public:
+ QNonNativeFileDialog(QWidget *parent = 0, const QString &caption = QString(), const QString &directory = QString(), const QString &filter = QString())
+ : QFileDialog(parent, caption, directory, filter)
+ {
+ setOption(QFileDialog::DontUseNativeDialog, true);
+ }
+};
+
+class tst_QFiledialog : public QObject
+{
+Q_OBJECT
+
+public:
+ tst_QFiledialog();
+ virtual ~tst_QFiledialog();
+
+public slots:
+ void init();
+ void cleanup();
+
+private slots:
+ void currentChangedSignal();
+ void directoryEnteredSignal();
+ void filesSelectedSignal_data();
+ void filesSelectedSignal();
+ void filterSelectedSignal();
+
+ void args();
+ void directory();
+ void completer_data();
+ void completer();
+ void completer_up();
+ void acceptMode();
+ void confirmOverwrite();
+ void defaultSuffix();
+ void fileMode();
+ void filters();
+ void history();
+ void iconProvider();
+ void isReadOnly();
+ void itemDelegate();
+ void labelText();
+ void resolveSymlinks();
+ void selectFile_data();
+ void selectFile();
+ void selectFiles();
+ void selectFilter();
+ void viewMode();
+ void proxymodel();
+ void setNameFilter();
+ void focus();
+ void caption();
+ void historyBack();
+ void historyForward();
+ void disableSaveButton_data();
+ void disableSaveButton();
+ void saveButtonText_data();
+ void saveButtonText();
+ void clearLineEdit();
+ void enableChooseButton();
+ void hooks();
+#if defined(Q_OS_UNIX) && defined(QT_BUILD_INTERNAL)
+ void tildeExpansion_data();
+ void tildeExpansion();
+#endif
+
+private:
+ QByteArray userSettings;
+};
+
+tst_QFiledialog::tst_QFiledialog()
+{
+}
+
+tst_QFiledialog::~tst_QFiledialog()
+{
+}
+
+void tst_QFiledialog::init()
+{
+ // Save the developers settings so they don't get mad when their sidebar folders are gone.
+ QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+ settings.beginGroup(QLatin1String("Qt"));
+ userSettings = settings.value(QLatin1String("filedialog")).toByteArray();
+ settings.remove(QLatin1String("filedialog"));
+
+ // populate it with some default settings
+ QNonNativeFileDialog fd;
+#if defined(Q_OS_WINCE)
+ QTest::qWait(1000);
+#endif
+}
+
+void tst_QFiledialog::cleanup()
+{
+ QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+ settings.beginGroup(QLatin1String("Qt"));
+ settings.setValue(QLatin1String("filedialog"), userSettings);
+}
+
+class MyAbstractItemDelegate : public QAbstractItemDelegate
+{
+public:
+ MyAbstractItemDelegate() : QAbstractItemDelegate() {};
+ void paint(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const {}
+ QSize sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const { return QSize(); }
+};
+
+// emitted any time the selection model emits current changed
+void tst_QFiledialog::currentChangedSignal()
+{
+ QNonNativeFileDialog fd;
+ fd.setViewMode(QFileDialog::List);
+ QSignalSpy spyCurrentChanged(&fd, SIGNAL(currentChanged(const QString &)));
+
+ QListView* listView = qFindChild<QListView*>(&fd, "listView");
+ QVERIFY(listView);
+ fd.setDirectory(QDir::root());
+ QModelIndex root = listView->rootIndex();
+ QTRY_COMPARE(listView->model()->rowCount(root) > 0, true);
+
+ QModelIndex folder;
+ for (int i = 0; i < listView->model()->rowCount(root); ++i) {
+ folder = listView->model()->index(i, 0, root);
+ if (listView->model()->hasChildren(folder))
+ break;
+ }
+ QVERIFY(listView->model()->hasChildren(folder));
+ listView->setCurrentIndex(folder);
+
+ QCOMPARE(spyCurrentChanged.count(), 1);
+}
+
+// only emitted from the views, sidebar, or lookin combo
+void tst_QFiledialog::directoryEnteredSignal()
+{
+#if defined QT_BUILD_INTERNAL
+ QNonNativeFileDialog fd(0, "", QDir::root().path());
+ fd.setOptions(QFileDialog::DontUseNativeDialog);
+ fd.show();
+ QTRY_COMPARE(fd.isVisible(), true);
+ QSignalSpy spyDirectoryEntered(&fd, SIGNAL(directoryEntered(const QString &)));
+
+ // sidebar
+ QSidebar *sidebar = qFindChild<QSidebar*>(&fd, "sidebar");
+ sidebar->setCurrentIndex(sidebar->model()->index(1, 0));
+ QTest::keyPress(sidebar->viewport(), Qt::Key_Return);
+ QCOMPARE(spyDirectoryEntered.count(), 1);
+ spyDirectoryEntered.clear();
+
+ // lookInCombo
+ QComboBox *comboBox = qFindChild<QComboBox*>(&fd, "lookInCombo");
+ comboBox->showPopup();
+ QVERIFY(comboBox->view()->model()->index(1, 0).isValid());
+ comboBox->view()->setCurrentIndex(comboBox->view()->model()->index(1, 0));
+ QTest::keyPress(comboBox->view()->viewport(), Qt::Key_Return);
+ QCOMPARE(spyDirectoryEntered.count(), 1);
+ spyDirectoryEntered.clear();
+
+ // view
+ /*
+ // platform specific
+ fd.setViewMode(QFileDialog::ViewMode(QFileDialog::List));
+ QListView* listView = qFindChild<QListView*>(&fd, "listView");
+ QVERIFY(listView);
+ QModelIndex root = listView->rootIndex();
+ QTRY_COMPARE(listView->model()->rowCount(root) > 0, true);
+
+ QModelIndex folder;
+ for (int i = 0; i < listView->model()->rowCount(root); ++i) {
+ folder = listView->model()->index(i, 0, root);
+ if (listView->model()->hasChildren(folder))
+ break;
+ }
+ QVERIFY(listView->model()->hasChildren(folder));
+ listView->setCurrentIndex(folder);
+ QTRY_COMPARE((listView->indexAt(listView->visualRect(folder).center())), folder);
+ QTest::mouseDClick(listView->viewport(), Qt::LeftButton, 0, listView->visualRect(folder).center());
+ QTRY_COMPARE(spyDirectoryEntered.count(), 1);
+ */
+#endif
+}
+
+Q_DECLARE_METATYPE(QFileDialog::FileMode)
+void tst_QFiledialog::filesSelectedSignal_data()
+{
+ QTest::addColumn<QFileDialog::FileMode>("fileMode");
+ QTest::newRow("any") << QFileDialog::AnyFile;
+ QTest::newRow("existing") << QFileDialog::ExistingFile;
+ QTest::newRow("directory") << QFileDialog::Directory;
+ QTest::newRow("directoryOnly") << QFileDialog::DirectoryOnly;
+ QTest::newRow("existingFiles") << QFileDialog::ExistingFiles;
+}
+
+// emitted when the dialog closes with the selected files
+void tst_QFiledialog::filesSelectedSignal()
+{
+ QNonNativeFileDialog fd;
+ fd.setViewMode(QFileDialog::List);
+ fd.setOptions(QFileDialog::DontUseNativeDialog);
+ QDir testDir(SRCDIR);
+ fd.setDirectory(testDir);
+ QFETCH(QFileDialog::FileMode, fileMode);
+ fd.setFileMode(fileMode);
+ QSignalSpy spyFilesSelected(&fd, SIGNAL(filesSelected(const QStringList &)));
+
+ fd.show();
+ QTest::qWait(500);
+ QListView *listView = qFindChild<QListView*>(&fd, "listView");
+ QVERIFY(listView);
+
+ QModelIndex root = listView->rootIndex();
+ QTRY_COMPARE(listView->model()->rowCount(root) > 0, true);
+ QModelIndex file;
+ for (int i = 0; i < listView->model()->rowCount(root); ++i) {
+ file = listView->model()->index(i, 0, root);
+ if (fileMode == QFileDialog::Directory || fileMode == QFileDialog::DirectoryOnly) {
+ if (listView->model()->hasChildren(file))
+ break;
+ } else {
+ if (!listView->model()->hasChildren(file))
+ break;
+ }
+ file = QModelIndex();
+ }
+ QVERIFY(file.isValid());
+ listView->selectionModel()->select(file, QItemSelectionModel::Select | QItemSelectionModel::Rows);
+ listView->setCurrentIndex(file);
+
+ QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox*>(&fd, "buttonBox");
+ QPushButton *button = buttonBox->button(QDialogButtonBox::Open);
+ QVERIFY(button);
+ QVERIFY(button->isEnabled());
+ button->animateClick();
+ QTRY_COMPARE(fd.isVisible(), false);
+ QCOMPARE(spyFilesSelected.count(), 1);
+}
+
+// only emitted when the combo box is activated
+void tst_QFiledialog::filterSelectedSignal()
+{
+ QNonNativeFileDialog fd;
+ fd.setAcceptMode(QFileDialog::AcceptSave);
+ fd.show();
+ QSignalSpy spyFilterSelected(&fd, SIGNAL(filterSelected(const QString &)));
+
+ QStringList filterChoices;
+ filterChoices << "Image files (*.png *.xpm *.jpg)"
+ << "Text files (*.txt)"
+ << "Any files (*.*)";
+ fd.setFilters(filterChoices);
+ QCOMPARE(fd.filters(), filterChoices);
+
+ QComboBox *filters = qFindChild<QComboBox*>(&fd, "fileTypeCombo");
+ QVERIFY(filters);
+ QVERIFY(filters->view());
+ QCOMPARE(filters->isVisible(), true);
+
+ QTest::keyPress(filters, Qt::Key_Down);
+
+ QCOMPARE(spyFilterSelected.count(), 1);
+}
+
+void tst_QFiledialog::args()
+{
+ QWidget *parent = 0;
+ QString caption = "caption";
+ QString directory = QDir::tempPath();
+ QString filter = "*.mp3";
+ QNonNativeFileDialog fd(parent, caption, directory, filter);
+ QCOMPARE(fd.parent(), (QObject *)parent);
+ QCOMPARE(fd.windowTitle(), caption);
+#ifndef Q_OS_WIN
+ QCOMPARE(fd.directory(), QDir(directory));
+#endif
+ QCOMPARE(fd.filters(), QStringList(filter));
+}
+
+void tst_QFiledialog::directory()
+{
+ QNonNativeFileDialog fd;
+ fd.setViewMode(QFileDialog::List);
+ QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
+ QVERIFY(model);
+ fd.setDirectory(QDir::currentPath());
+ QSignalSpy spyCurrentChanged(&fd, SIGNAL(currentChanged(const QString &)));
+ QSignalSpy spyDirectoryEntered(&fd, SIGNAL(directoryEntered(const QString &)));
+ QSignalSpy spyFilesSelected(&fd, SIGNAL(filesSelected(const QStringList &)));
+ QSignalSpy spyFilterSelected(&fd, SIGNAL(filterSelected(const QString &)));
+
+ QCOMPARE(QDir::current().absolutePath(), fd.directory().absolutePath());
+ QDir temp = QDir::temp();
+ QString tempPath = temp.absolutePath();
+#ifdef Q_OS_WIN
+ // since the user can have lowercase temp dir, check that we are actually case-insensitive.
+ tempPath = tempPath.toLower();
+#endif
+ fd.setDirectory(tempPath);
+#ifndef Q_OS_WIN
+ QCOMPARE(tempPath, fd.directory().absolutePath());
+#endif
+ QCOMPARE(spyCurrentChanged.count(), 0);
+ QCOMPARE(spyDirectoryEntered.count(), 0);
+ QCOMPARE(spyFilesSelected.count(), 0);
+ QCOMPARE(spyFilterSelected.count(), 0);
+
+ // Check my way
+ QList<QListView*> list = qFindChildren<QListView*>(&fd, "listView");
+ QVERIFY(list.count() > 0);
+#ifdef Q_OS_WIN
+ QCOMPARE(list.at(0)->rootIndex().data().toString().toLower(), temp.dirName().toLower());
+#else
+ QCOMPARE(list.at(0)->rootIndex().data().toString(), temp.dirName());
+#endif
+ QNonNativeFileDialog *dlg = new QNonNativeFileDialog(0, "", tempPath);
+ QCOMPARE(model->index(tempPath), model->index(dlg->directory().absolutePath()));
+ QCOMPARE(model->index(tempPath).data(QFileSystemModel::FileNameRole).toString(),
+ model->index(dlg->directory().absolutePath()).data(QFileSystemModel::FileNameRole).toString());
+ delete dlg;
+ dlg = new QNonNativeFileDialog();
+ QCOMPARE(model->index(tempPath), model->index(dlg->directory().absolutePath()));
+ delete dlg;
+}
+
+void tst_QFiledialog::completer_data()
+{
+ QTest::addColumn<QString>("startPath");
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<int>("expected");
+
+ QTest::newRow("r, 10") << "" << "r" << 10;
+ QTest::newRow("x, 0") << "" << "x" << 0;
+ QTest::newRow("../, -1") << "" << "../" << -1;
+
+ QTest::newRow("goto root") << QString() << QDir::rootPath() << -1;
+ QTest::newRow("start at root") << QDir::rootPath() << QString() << -1;
+
+ QDir root = QDir::root();
+ QStringList list = root.entryList();
+ QString folder;
+ for (int i = 0; i < list.count(); ++i) {
+ if (list.at(0) == QChar('.'))
+ continue;
+ QFileInfo info(QDir::rootPath() + list[i]);
+ if (info.isDir()) {
+ folder = QDir::rootPath() + list[i];
+ break;
+ }
+ }
+
+ QTest::newRow("start at one below root r") << folder << "r" << -1;
+ QTest::newRow("start at one below root ../") << folder << "../" << -1;
+}
+
+void tst_QFiledialog::completer()
+{
+ QFETCH(QString, input);
+ QFETCH(QString, startPath);
+ QFETCH(int, expected);
+
+ QString tempPath = QDir::tempPath() + '/' + "QFileDialogTestDir";
+ if (startPath.isEmpty())
+ startPath = tempPath;
+
+ startPath = QDir::cleanPath(startPath);
+
+ // make temp dir and files
+ {
+ QDir cleanup(tempPath);
+ QStringList x = cleanup.entryList();
+ for (int i = 0; i < x.count(); ++i)
+ QFile::remove(tempPath + '/' + x[i]);
+ cleanup.rmdir(tempPath);
+ }
+ QDir tmp(QDir::tempPath());
+ if (!tmp.exists(tempPath))
+ QVERIFY(tmp.mkdir("QFileDialogTestDir"));
+ QList<QTemporaryFile*> files;
+ QT_TRY {
+ for (int i = 0; i < 10; ++i) {
+ QScopedPointer<QTemporaryFile> file(new QTemporaryFile(tempPath + "/rXXXXXX"));
+ file->open();
+ files.append(file.take());
+ }
+
+ // ### flesh this out more
+ QNonNativeFileDialog fd(0,QString("Test it"),startPath);
+ fd.setOptions(QFileDialog::DontUseNativeDialog);
+ fd.show();
+ QVERIFY(fd.isVisible());
+ QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
+ QVERIFY(model);
+ QLineEdit *lineEdit = qFindChild<QLineEdit*>(&fd, "fileNameEdit");
+ QVERIFY(lineEdit);
+ QCompleter *completer = lineEdit->completer();
+ QVERIFY(completer);
+ QAbstractItemModel *cModel = completer->completionModel();
+ QVERIFY(cModel);
+
+ //wait a bit
+ QTest::qWait(500);
+
+ // path C:\depot\qt\examples\dialogs\standarddialogs
+ // files
+ // [debug] [release] [tmp] dialog dialog main makefile makefile.debug makefile.release standarddialgos
+ //
+ // d -> D:\ debug dialog.cpp dialog.h
+ // ..\ -> ..\classwizard ..\configdialog ..\dialogs.pro
+ // c -> C:\ control panel
+ // c: -> C:\ (nothing more)
+ // C:\ -> C:\, C:\_viminfo, ...
+ // \ -> \_viminfo
+ // c:\depot -> 'nothing'
+ // c:\depot\ -> C:\depot\devtools, C:\depot\dteske
+ QCOMPARE(model->index(fd.directory().path()), model->index(startPath));
+
+ if (input.isEmpty()) {
+ QModelIndex r = model->index(model->rootPath());
+ QVERIFY(model->rowCount(r) > 0);
+ QModelIndex idx = model->index(0, 0, r);
+ input = idx.data().toString().at(0);
+ }
+
+ // press 'keys' for the input
+ for (int i = 0; i < input.count(); ++i)
+ QTest::keyPress(lineEdit, input[i].toAscii());
+
+ QStringList expectedFiles;
+ if (expected == -1) {
+ QString fullPath = startPath.isEmpty() ? tempPath : startPath;
+ if (!fullPath.endsWith(QLatin1Char('/')))
+ fullPath.append(QLatin1Char('/'));
+ fullPath.append(input);
+ bool inputStartsWithRootPath = false;
+ if (input.startsWith(QDir::rootPath())) {
+ fullPath = input;
+ input.clear();
+ inputStartsWithRootPath = true;
+ }
+
+ QFileInfo fi(fullPath);
+ QDir x(fi.absolutePath());
+ expectedFiles = x.entryList(model->filter());
+ expected = 0;
+ if (input.startsWith(".."))
+ input.clear();
+ for (int ii = 0; ii < expectedFiles.count(); ++ii) {
+#if defined(Q_OS_WIN)
+ if (expectedFiles.at(ii).startsWith(input,Qt::CaseInsensitive))
+#else
+ if (expectedFiles.at(ii).startsWith(input))
+#endif
+ ++expected;
+ }
+ }
+
+ QTest::qWait(1000);
+ if (cModel->rowCount() != expected) {
+ for (int i = 0; i < cModel->rowCount(); ++i) {
+ QString file = cModel->index(i, 0).data().toString();
+ expectedFiles.removeAll(file);
+ }
+ //qDebug() << expectedFiles;
+ }
+
+ QTRY_COMPARE(cModel->rowCount(), expected);
+ } QT_CATCH(...) {
+ qDeleteAll(files);
+ QT_RETHROW;
+ }
+ qDeleteAll(files);
+}
+
+void tst_QFiledialog::completer_up()
+{
+ QNonNativeFileDialog fd;
+ fd.setOptions(QFileDialog::DontUseNativeDialog);
+ QSignalSpy spyCurrentChanged(&fd, SIGNAL(currentChanged(const QString &)));
+ QSignalSpy spyDirectoryEntered(&fd, SIGNAL(directoryEntered(const QString &)));
+ QSignalSpy spyFilesSelected(&fd, SIGNAL(filesSelected(const QStringList &)));
+ QSignalSpy spyFilterSelected(&fd, SIGNAL(filterSelected(const QString &)));
+
+ fd.show();
+ QLineEdit *lineEdit = qFindChild<QLineEdit*>(&fd, "fileNameEdit");
+ QVERIFY(lineEdit);
+ QCOMPARE(spyFilesSelected.count(), 0);
+ int depth = QDir::currentPath().split('/').count();
+ for (int i = 0; i <= depth * 3 + 1; ++i) {
+ lineEdit->insert("../");
+ qApp->processEvents();
+ }
+ QCOMPARE(spyCurrentChanged.count(), 0);
+ QCOMPARE(spyDirectoryEntered.count(), 0);
+ QCOMPARE(spyFilesSelected.count(), 0);
+ QCOMPARE(spyFilterSelected.count(), 0);
+}
+
+void tst_QFiledialog::acceptMode()
+{
+ QNonNativeFileDialog fd;
+ fd.show();
+
+ QToolButton* newButton = qFindChild<QToolButton*>(&fd, "newFolderButton");
+ QVERIFY(newButton);
+
+ // default
+ QCOMPARE(fd.acceptMode(), QFileDialog::AcceptOpen);
+ QCOMPARE(newButton && newButton->isVisible(), true);
+
+ //fd.setDetailsExpanded(true);
+ fd.setAcceptMode(QFileDialog::AcceptSave);
+ QCOMPARE(fd.acceptMode(), QFileDialog::AcceptSave);
+ QCOMPARE(newButton->isVisible(), true);
+
+ fd.setAcceptMode(QFileDialog::AcceptOpen);
+ QCOMPARE(fd.acceptMode(), QFileDialog::AcceptOpen);
+ QCOMPARE(newButton->isVisible(), true);
+}
+
+void tst_QFiledialog::confirmOverwrite()
+{
+ QNonNativeFileDialog fd;
+ QCOMPARE(fd.confirmOverwrite(), true);
+ fd.setConfirmOverwrite(true);
+ QCOMPARE(fd.confirmOverwrite(), true);
+ fd.setConfirmOverwrite(false);
+ QCOMPARE(fd.confirmOverwrite(), false);
+ fd.setConfirmOverwrite(true);
+ QCOMPARE(fd.confirmOverwrite(), true);
+}
+
+void tst_QFiledialog::defaultSuffix()
+{
+ QNonNativeFileDialog fd;
+ QCOMPARE(fd.defaultSuffix(), QString());
+ fd.setDefaultSuffix("txt");
+ QCOMPARE(fd.defaultSuffix(), QString("txt"));
+ fd.setDefaultSuffix(QString());
+ QCOMPARE(fd.defaultSuffix(), QString());
+}
+
+void tst_QFiledialog::fileMode()
+{
+ QNonNativeFileDialog fd;
+ QCOMPARE(fd.fileMode(), QFileDialog::AnyFile);
+ fd.setFileMode(QFileDialog::ExistingFile);
+ QCOMPARE(fd.fileMode(), QFileDialog::ExistingFile);
+ fd.setFileMode(QFileDialog::Directory);
+ QCOMPARE(fd.fileMode(), QFileDialog::Directory);
+ fd.setFileMode(QFileDialog::DirectoryOnly);
+ QCOMPARE(fd.fileMode(), QFileDialog::DirectoryOnly);
+ fd.setFileMode(QFileDialog::ExistingFiles);
+ QCOMPARE(fd.fileMode(), QFileDialog::ExistingFiles);
+}
+
+void tst_QFiledialog::caption()
+{
+ QNonNativeFileDialog fd;
+ fd.setWindowTitle("testing");
+ fd.setFileMode(QFileDialog::Directory);
+ QCOMPARE(fd.windowTitle(), QString("testing"));
+}
+
+void tst_QFiledialog::filters()
+{
+ QNonNativeFileDialog fd;
+ fd.setOptions(QFileDialog::DontUseNativeDialog);
+ QSignalSpy spyCurrentChanged(&fd, SIGNAL(currentChanged(const QString &)));
+ QSignalSpy spyDirectoryEntered(&fd, SIGNAL(directoryEntered(const QString &)));
+ QSignalSpy spyFilesSelected(&fd, SIGNAL(filesSelected(const QStringList &)));
+ QSignalSpy spyFilterSelected(&fd, SIGNAL(filterSelected(const QString &)));
+ QCOMPARE(fd.filters(), QStringList("All Files (*)"));
+
+ // effects
+ QList<QComboBox*> views = qFindChildren<QComboBox*>(&fd, "fileTypeCombo");
+ QVERIFY(views.count() == 1);
+ QCOMPARE(views.at(0)->isVisible(), false);
+
+ QStringList filters;
+ filters << "Image files (*.png *.xpm *.jpg)"
+ << "Text files (*.txt)"
+ << "Any files (*.*)";
+ fd.setFilters(filters);
+ QCOMPARE(views.at(0)->isVisible(), false);
+ fd.show();
+ fd.setAcceptMode(QFileDialog::AcceptSave);
+ QCOMPARE(views.at(0)->isVisible(), true);
+ QCOMPARE(fd.filters(), filters);
+ fd.setFilter("Image files (*.png *.xpm *.jpg);;Text files (*.txt);;Any files (*.*)");
+ QCOMPARE(fd.filters(), filters);
+ QCOMPARE(spyCurrentChanged.count(), 0);
+ QCOMPARE(spyDirectoryEntered.count(), 0);
+ QCOMPARE(spyFilesSelected.count(), 0);
+ QCOMPARE(spyFilterSelected.count(), 0);
+
+ // setting shouldn't emit any signals
+ for (int i = views.at(0)->currentIndex(); i < views.at(0)->count(); ++i)
+ views.at(0)->setCurrentIndex(i);
+ QCOMPARE(spyFilterSelected.count(), 0);
+
+ //Let check if filters with whitespaces
+ QNonNativeFileDialog fd2;
+ QStringList expected;
+ expected << "C++ Source Files(*.cpp)";
+ expected << "Any(*.*)";
+ fd2.setFilter("C++ Source Files(*.cpp);;Any(*.*)");
+ QCOMPARE(expected, fd2.filters());
+ fd2.setFilter("C++ Source Files(*.cpp) ;;Any(*.*)");
+ QCOMPARE(expected, fd2.filters());
+ fd2.setFilter("C++ Source Files(*.cpp);; Any(*.*)");
+ QCOMPARE(expected, fd2.filters());
+ fd2.setFilter(" C++ Source Files(*.cpp);; Any(*.*)");
+ QCOMPARE(expected, fd2.filters());
+ fd2.setFilter("C++ Source Files(*.cpp) ;; Any(*.*)");
+ QCOMPARE(expected, fd2.filters());
+}
+
+void tst_QFiledialog::selectFilter()
+{
+ QNonNativeFileDialog fd;
+ QSignalSpy spyFilterSelected(&fd, SIGNAL(filterSelected(const QString &)));
+ QCOMPARE(fd.selectedFilter(), QString("All Files (*)"));
+ QStringList filters;
+ filters << "Image files (*.png *.xpm *.jpg)"
+ << "Text files (*.txt)"
+ << "Any files (*.*)";
+ fd.setFilters(filters);
+ QCOMPARE(fd.selectedFilter(), filters.at(0));
+ fd.selectFilter(filters.at(1));
+ QCOMPARE(fd.selectedFilter(), filters.at(1));
+ fd.selectFilter(filters.at(2));
+ QCOMPARE(fd.selectedFilter(), filters.at(2));
+
+ fd.selectFilter("bob");
+ QCOMPARE(fd.selectedFilter(), filters.at(2));
+ fd.selectFilter("");
+ QCOMPARE(fd.selectedFilter(), filters.at(2));
+ QCOMPARE(spyFilterSelected.count(), 0);
+}
+
+void tst_QFiledialog::history()
+{
+ QNonNativeFileDialog fd;
+ fd.setViewMode(QFileDialog::List);
+ QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
+ QVERIFY(model);
+ QSignalSpy spyCurrentChanged(&fd, SIGNAL(currentChanged(const QString &)));
+ QSignalSpy spyDirectoryEntered(&fd, SIGNAL(directoryEntered(const QString &)));
+ QSignalSpy spyFilesSelected(&fd, SIGNAL(filesSelected(const QStringList &)));
+ QSignalSpy spyFilterSelected(&fd, SIGNAL(filterSelected(const QString &)));
+ QCOMPARE(model->index(fd.history().first()), model->index(QDir::toNativeSeparators(fd.directory().absolutePath())));
+ fd.setDirectory(QDir::current().absolutePath());
+ QStringList history;
+ history << QDir::toNativeSeparators(QDir::current().absolutePath())
+ << QDir::toNativeSeparators(QDir::home().absolutePath())
+ << QDir::toNativeSeparators(QDir::temp().absolutePath());
+ fd.setHistory(history);
+ if (fd.history() != history) {
+ qDebug() << fd.history() << history;
+ // quick and dirty output for windows failure.
+ QListView* list = qFindChild<QListView*>(&fd, "listView");
+ QVERIFY(list);
+ QModelIndex root = list->rootIndex();
+ while (root.isValid()) {
+ qDebug() << root.data();
+ root = root.parent();
+ }
+ }
+ QCOMPARE(fd.history(), history);
+
+ QStringList badHistory;
+ badHistory << "junk";
+ fd.setHistory(badHistory);
+ badHistory << QDir::toNativeSeparators(QDir::current().absolutePath());
+ QCOMPARE(fd.history(), badHistory);
+
+ QCOMPARE(spyCurrentChanged.count(), 0);
+ QCOMPARE(spyDirectoryEntered.count(), 0);
+ QCOMPARE(spyFilesSelected.count(), 0);
+ QCOMPARE(spyFilterSelected.count(), 0);
+}
+
+void tst_QFiledialog::iconProvider()
+{
+ QNonNativeFileDialog *fd = new QNonNativeFileDialog();
+ QVERIFY(fd->iconProvider() != 0);
+ QFileIconProvider *ip = new QFileIconProvider();
+ fd->setIconProvider(ip);
+ QCOMPARE(fd->iconProvider(), ip);
+ delete fd;
+ delete ip;
+}
+
+void tst_QFiledialog::isReadOnly()
+{
+ QNonNativeFileDialog fd;
+
+ QPushButton* newButton = qFindChild<QPushButton*>(&fd, "newFolderButton");
+ QAction* renameAction = qFindChild<QAction*>(&fd, "qt_rename_action");
+ QAction* deleteAction = qFindChild<QAction*>(&fd, "qt_delete_action");
+
+ QCOMPARE(fd.isReadOnly(), false);
+
+ // This is dependent upon the file/dir, find cross platform way to test
+ //fd.setDirectory(QDir::home());
+ //QCOMPARE(newButton && newButton->isEnabled(), true);
+ //QCOMPARE(renameAction && renameAction->isEnabled(), true);
+ //QCOMPARE(deleteAction && deleteAction->isEnabled(), true);
+
+ fd.setReadOnly(true);
+ QCOMPARE(fd.isReadOnly(), true);
+
+ QCOMPARE(newButton && newButton->isEnabled(), false);
+ QCOMPARE(renameAction && renameAction->isEnabled(), false);
+ QCOMPARE(deleteAction && deleteAction->isEnabled(), false);
+}
+
+void tst_QFiledialog::itemDelegate()
+{
+ QNonNativeFileDialog fd;
+ QVERIFY(fd.itemDelegate() != 0);
+ QItemDelegate *id = new QItemDelegate(&fd);
+ fd.setItemDelegate(id);
+ QCOMPARE(fd.itemDelegate(), (QAbstractItemDelegate *)id);
+}
+
+void tst_QFiledialog::labelText()
+{
+ QNonNativeFileDialog fd;
+ QDialogButtonBox buttonBox;
+ QPushButton *cancelButton = buttonBox.addButton(QDialogButtonBox::Cancel);
+ QCOMPARE(fd.labelText(QFileDialog::LookIn), QString("Look in:"));
+ QCOMPARE(fd.labelText(QFileDialog::FileName), QString("File &name:"));
+ QCOMPARE(fd.labelText(QFileDialog::FileType), QString("Files of type:"));
+ QCOMPARE(fd.labelText(QFileDialog::Accept), QString("&Open")); ///### see task 241462
+ QCOMPARE(fd.labelText(QFileDialog::Reject), cancelButton->text());
+
+ fd.setLabelText(QFileDialog::LookIn, "1");
+ QCOMPARE(fd.labelText(QFileDialog::LookIn), QString("1"));
+ fd.setLabelText(QFileDialog::FileName, "2");
+ QCOMPARE(fd.labelText(QFileDialog::FileName), QString("2"));
+ fd.setLabelText(QFileDialog::FileType, "3");
+ QCOMPARE(fd.labelText(QFileDialog::FileType), QString("3"));
+ fd.setLabelText(QFileDialog::Accept, "4");
+ QCOMPARE(fd.labelText(QFileDialog::Accept), QString("4"));
+ fd.setLabelText(QFileDialog::Reject, "5");
+ QCOMPARE(fd.labelText(QFileDialog::Reject), QString("5"));
+}
+
+void tst_QFiledialog::resolveSymlinks()
+{
+ QNonNativeFileDialog fd;
+
+ // default
+ QCOMPARE(fd.resolveSymlinks(), true);
+ fd.setResolveSymlinks(false);
+ QCOMPARE(fd.resolveSymlinks(), false);
+ fd.setResolveSymlinks(true);
+ QCOMPARE(fd.resolveSymlinks(), true);
+
+ // the file dialog doesn't do anything based upon this, just passes it to the model
+ // the model should fully test it, don't test it here
+}
+
+void tst_QFiledialog::selectFile_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<int>("count");
+ QTest::newRow("null") << QString() << 1;
+ QTest::newRow("file") << "foo" << 1;
+ QTest::newRow("tmp") << "temp" << 1;
+}
+
+void tst_QFiledialog::selectFile()
+{
+ QFETCH(QString, file);
+ QFETCH(int, count);
+ QNonNativeFileDialog fd;
+ QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
+ QVERIFY(model);
+ fd.setDirectory(QDir::currentPath());
+ // default value
+ QCOMPARE(fd.selectedFiles().count(), 1);
+
+ QTemporaryFile tempFile(QDir::tempPath() + "/aXXXXXX");
+ bool inTemp = (file == "temp");
+ if (inTemp) {
+ tempFile.open();
+ file = tempFile.fileName();
+ }
+
+ fd.selectFile(file);
+ QCOMPARE(fd.selectedFiles().count(), count);
+ if (inTemp) {
+ QCOMPARE(model->index(fd.directory().path()), model->index(QDir::tempPath()));
+ } else {
+ QCOMPARE(model->index(fd.directory().path()), model->index(QDir::currentPath()));
+ }
+}
+
+void tst_QFiledialog::selectFiles()
+{
+ QNonNativeFileDialog fd;
+ fd.setViewMode(QFileDialog::List);
+ QString tempPath = QDir::tempPath() + '/' + "QFileDialogTestDir4SelectFiles";
+ QDir dir;
+ QVERIFY(dir.mkpath(tempPath));
+ fd.setDirectory(tempPath);
+ QSignalSpy spyCurrentChanged(&fd, SIGNAL(currentChanged(const QString &)));
+ QSignalSpy spyDirectoryEntered(&fd, SIGNAL(directoryEntered(const QString &)));
+ QSignalSpy spyFilesSelected(&fd, SIGNAL(filesSelected(const QStringList &)));
+ QSignalSpy spyFilterSelected(&fd, SIGNAL(filterSelected(const QString &)));
+ fd.show();
+ fd.setFileMode(QFileDialog::ExistingFiles);
+
+ QString filesPath = fd.directory().absolutePath();
+ for (int i=0; i < 5; ++i) {
+ QFile file(filesPath + QString::fromLatin1("/qfiledialog_auto_test_not_pres_%1").arg(i));
+ file.open(QIODevice::WriteOnly);
+ file.resize(1024);
+ file.flush();
+ file.close();
+ }
+
+ // Get a list of files in the view and then get the corresponding index's
+ QStringList list = fd.directory().entryList(QDir::Files);
+ QModelIndexList toSelect;
+ QVERIFY(list.count() > 1);
+ QListView* listView = qFindChild<QListView*>(&fd, "listView");
+ QVERIFY(listView);
+ for (int i = 0; i < list.count(); ++i) {
+ fd.selectFile(fd.directory().path() + "/" + list.at(i));
+#if defined(Q_WS_MAC) || defined(Q_WS_WIN)
+ QEXPECT_FAIL("", "This test does not work on Mac or Windows", Abort);
+#endif
+ QTRY_VERIFY(!listView->selectionModel()->selectedRows().isEmpty());
+ toSelect.append(listView->selectionModel()->selectedRows().last());
+ }
+ QCOMPARE(spyFilesSelected.count(), 0);
+
+ listView->selectionModel()->clear();
+ QCOMPARE(spyFilesSelected.count(), 0);
+
+ // select the indexes
+ for (int i = 0; i < toSelect.count(); ++i) {
+ listView->selectionModel()->select(toSelect.at(i),
+ QItemSelectionModel::Select | QItemSelectionModel::Rows);
+ }
+ QCOMPARE(fd.selectedFiles().count(), toSelect.count());
+ QCOMPARE(spyCurrentChanged.count(), 0);
+ QCOMPARE(spyDirectoryEntered.count(), 0);
+ QCOMPARE(spyFilesSelected.count(), 0);
+ QCOMPARE(spyFilterSelected.count(), 0);
+ for (int i=0; i < 5; ++i)
+ QFile::remove(filesPath + QString::fromLatin1("/qfiledialog_auto_test_not_pres_%1").arg(i));
+
+ //If the selection is invalid then we fill the line edit but without the /
+ QNonNativeFileDialog * dialog = new QNonNativeFileDialog( 0, "Save" );
+ dialog->setFileMode( QFileDialog::AnyFile );
+ dialog->setAcceptMode( QFileDialog::AcceptSave );
+ QString temporary = QDir::tempPath() + QLatin1String("/blah");
+ dialog->selectFile(temporary);
+ dialog->show();
+ QTest::qWait(500);
+ QLineEdit *lineEdit = qFindChild<QLineEdit*>(dialog, "fileNameEdit");
+ QVERIFY(lineEdit);
+ QCOMPARE(lineEdit->text(),QLatin1String("blah"));
+ delete dialog;
+}
+
+void tst_QFiledialog::viewMode()
+{
+ QNonNativeFileDialog fd;
+ fd.setViewMode(QFileDialog::List);
+ fd.show();
+
+ // find widgets
+ QList<QTreeView*> treeView = qFindChildren<QTreeView*>(&fd, "treeView");
+ QCOMPARE(treeView.count(), 1);
+ QList<QListView*> listView = qFindChildren<QListView*>(&fd, "listView");
+ QCOMPARE(listView.count(), 1);
+ QList<QToolButton*> listButton = qFindChildren<QToolButton*>(&fd, "listModeButton");
+ QCOMPARE(listButton.count(), 1);
+ QList<QToolButton*> treeButton = qFindChildren<QToolButton*>(&fd, "detailModeButton");
+ QCOMPARE(treeButton.count(), 1);
+
+ // default value
+ QCOMPARE(fd.viewMode(), QFileDialog::List);
+
+ // detail
+ fd.setViewMode(QFileDialog::ViewMode(QFileDialog::Detail));
+
+ QCOMPARE(QFileDialog::ViewMode(QFileDialog::Detail), fd.viewMode());
+ QCOMPARE(listView.at(0)->isVisible(), false);
+ QCOMPARE(listButton.at(0)->isDown(), false);
+ QCOMPARE(treeView.at(0)->isVisible(), true);
+ QCOMPARE(treeButton.at(0)->isDown(), true);
+
+ // list
+ fd.setViewMode(QFileDialog::ViewMode(QFileDialog::List));
+
+ QCOMPARE(QFileDialog::ViewMode(QFileDialog::List), fd.viewMode());
+ QCOMPARE(treeView.at(0)->isVisible(), false);
+ QCOMPARE(treeButton.at(0)->isDown(), false);
+ QCOMPARE(listView.at(0)->isVisible(), true);
+ QCOMPARE(listButton.at(0)->isDown(), true);
+}
+
+void tst_QFiledialog::proxymodel()
+{
+ QNonNativeFileDialog fd;
+ QCOMPARE(fd.proxyModel(), (QAbstractProxyModel*)0);
+
+ fd.setProxyModel(0);
+ QCOMPARE(fd.proxyModel(), (QAbstractProxyModel*)0);
+
+ QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(&fd);
+ fd.setProxyModel(proxyModel);
+ QCOMPARE(fd.proxyModel(), (QAbstractProxyModel *)proxyModel);
+
+ fd.setProxyModel(0);
+ QCOMPARE(fd.proxyModel(), (QAbstractProxyModel*)0);
+}
+
+void tst_QFiledialog::setNameFilter()
+{
+ QNonNativeFileDialog fd;
+ fd.setFilter(QString());
+ fd.setFilters(QStringList());
+}
+
+void tst_QFiledialog::focus()
+{
+ QNonNativeFileDialog fd;
+ fd.setDirectory(QDir::currentPath());
+ fd.show();
+ QApplication::setActiveWindow(&fd);
+ QTest::qWaitForWindowShown(&fd);
+ QTRY_COMPARE(fd.isVisible(), true);
+ QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget*>(&fd));
+ qApp->processEvents();
+
+ // make sure the tests work with focus follows mouse
+ QCursor::setPos(fd.geometry().center());
+ QApplication::syncX();
+
+ QList<QWidget*> treeView = qFindChildren<QWidget*>(&fd, "fileNameEdit");
+ QCOMPARE(treeView.count(), 1);
+ QVERIFY(treeView.at(0));
+ QTRY_COMPARE(treeView.at(0)->hasFocus(), true);
+ QCOMPARE(treeView.at(0)->hasFocus(), true);
+}
+
+
+void tst_QFiledialog::historyBack()
+{
+ QNonNativeFileDialog fd;
+ QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
+ QVERIFY(model);
+ QToolButton *backButton = qFindChild<QToolButton*>(&fd, "backButton");
+ QVERIFY(backButton);
+ QToolButton *forwardButton = qFindChild<QToolButton*>(&fd, "forwardButton");
+ QVERIFY(forwardButton);
+
+ QSignalSpy spy(model, SIGNAL(rootPathChanged(const QString &)));
+
+ QString home = fd.directory().absolutePath();
+ QString desktop = QDir::homePath();
+ QString temp = QDir::tempPath();
+
+ QCOMPARE(backButton->isEnabled(), false);
+ QCOMPARE(forwardButton->isEnabled(), false);
+ fd.setDirectory(temp);
+ qApp->processEvents();
+ QCOMPARE(backButton->isEnabled(), true);
+ QCOMPARE(forwardButton->isEnabled(), false);
+ fd.setDirectory(desktop);
+ QCOMPARE(spy.count(), 2);
+
+ backButton->click();
+ qApp->processEvents();
+ QCOMPARE(backButton->isEnabled(), true);
+ QCOMPARE(forwardButton->isEnabled(), true);
+ QCOMPARE(spy.count(), 3);
+ QString currentPath = qVariantValue<QString>(spy.last().first());
+ QCOMPARE(model->index(currentPath), model->index(temp));
+
+ backButton->click();
+ currentPath = qVariantValue<QString>(spy.last().first());
+ QCOMPARE(currentPath, home);
+ QCOMPARE(backButton->isEnabled(), false);
+ QCOMPARE(forwardButton->isEnabled(), true);
+ QCOMPARE(spy.count(), 4);
+
+ // nothing should change at this point
+ backButton->click();
+ QCOMPARE(spy.count(), 4);
+ QCOMPARE(backButton->isEnabled(), false);
+ QCOMPARE(forwardButton->isEnabled(), true);
+}
+
+void tst_QFiledialog::historyForward()
+{
+ QNonNativeFileDialog fd;
+ fd.setDirectory(QDir::currentPath());
+ QToolButton *backButton = qFindChild<QToolButton*>(&fd, "backButton");
+ QVERIFY(backButton);
+ QToolButton *forwardButton = qFindChild<QToolButton*>(&fd, "forwardButton");
+ QVERIFY(forwardButton);
+
+ QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
+ QVERIFY(model);
+ QSignalSpy spy(model, SIGNAL(rootPathChanged(const QString &)));
+
+ QString home = fd.directory().absolutePath();
+ QString desktop = QDir::homePath();
+ QString temp = QDir::tempPath();
+
+ fd.setDirectory(home);
+ fd.setDirectory(temp);
+ fd.setDirectory(desktop);
+
+ backButton->click();
+ QCOMPARE(forwardButton->isEnabled(), true);
+ QCOMPARE(model->index(qVariantValue<QString>(spy.last().first())), model->index(temp));
+
+ forwardButton->click();
+ QCOMPARE(model->index(qVariantValue<QString>(spy.last().first())), model->index(desktop));
+ QCOMPARE(backButton->isEnabled(), true);
+ QCOMPARE(forwardButton->isEnabled(), false);
+ QCOMPARE(spy.count(), 4);
+
+ backButton->click();
+ QCOMPARE(model->index(qVariantValue<QString>(spy.last().first())), model->index(temp));
+ QCOMPARE(backButton->isEnabled(), true);
+
+ backButton->click();
+ QCOMPARE(model->index(qVariantValue<QString>(spy.last().first())), model->index(home));
+ QCOMPARE(backButton->isEnabled(), false);
+ QCOMPARE(forwardButton->isEnabled(), true);
+ QCOMPARE(spy.count(), 6);
+
+ forwardButton->click();
+ QCOMPARE(model->index(qVariantValue<QString>(spy.last().first())), model->index(temp));
+ backButton->click();
+ QCOMPARE(model->index(qVariantValue<QString>(spy.last().first())), model->index(home));
+ QCOMPARE(spy.count(), 8);
+
+ forwardButton->click();
+ QCOMPARE(model->index(qVariantValue<QString>(spy.last().first())), model->index(temp));
+ forwardButton->click();
+ QCOMPARE(model->index(qVariantValue<QString>(spy.last().first())), model->index(desktop));
+
+ backButton->click();
+ QCOMPARE(model->index(qVariantValue<QString>(spy.last().first())), model->index(temp));
+ backButton->click();
+ QCOMPARE(model->index(qVariantValue<QString>(spy.last().first())), model->index(home));
+ fd.setDirectory(desktop);
+ QCOMPARE(forwardButton->isEnabled(), false);
+}
+
+void tst_QFiledialog::disableSaveButton_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("isEnabled");
+
+ QTest::newRow("valid path") << QDir::temp().absolutePath() + QDir::separator() + "qfiledialog.new_file" << true;
+ QTest::newRow("no path") << "" << false;
+#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_OPENBSD)
+ QTest::newRow("too long path") << "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii" << false;
+#endif
+ QTest::newRow("file") << "foo.html" << true;
+}
+
+void tst_QFiledialog::disableSaveButton()
+{
+ QFETCH(QString, path);
+ QFETCH(bool, isEnabled);
+
+ QNonNativeFileDialog fd(0, "caption", path);
+ fd.setAcceptMode(QFileDialog::AcceptSave);
+ QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox*>(&fd, "buttonBox");
+ QPushButton *button = buttonBox->button(QDialogButtonBox::Save);
+ QVERIFY(button);
+ QCOMPARE(button->isEnabled(), isEnabled);
+}
+
+void tst_QFiledialog::saveButtonText_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<QString>("label");
+ QTest::addColumn<QString>("caption");
+
+ QTest::newRow("empty path") << "" << QString() << QFileDialog::tr("&Save");
+ QTest::newRow("file path") << "qfiledialog.new_file" << QString() << QFileDialog::tr("&Save");
+ QTest::newRow("dir") << QDir::temp().absolutePath() << QString() << QFileDialog::tr("&Open");
+ QTest::newRow("setTextLabel") << "qfiledialog.new_file" << "Mooo" << "Mooo";
+ QTest::newRow("dir & label") << QDir::temp().absolutePath() << "Poo" << QFileDialog::tr("&Open");
+}
+
+void tst_QFiledialog::saveButtonText()
+{
+ QFETCH(QString, path);
+ QFETCH(QString, label);
+ QFETCH(QString, caption);
+
+ QNonNativeFileDialog fd(0, "auto test", QDir::temp().absolutePath());
+ fd.setAcceptMode(QFileDialog::AcceptSave);
+ if (!label.isNull())
+ fd.setLabelText(QFileDialog::Accept, label);
+ fd.setDirectory(QDir::temp());
+ fd.selectFile(path);
+ QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox*>(&fd, "buttonBox");
+ QVERIFY(buttonBox);
+ QPushButton *button = buttonBox->button(QDialogButtonBox::Save);
+ QVERIFY(button);
+ QCOMPARE(button->text(), caption);
+}
+
+void tst_QFiledialog::clearLineEdit()
+{
+ QNonNativeFileDialog fd(0, "caption", "foo");
+ fd.setViewMode(QFileDialog::List);
+ fd.setFileMode(QFileDialog::AnyFile);
+ fd.setOptions(QFileDialog::DontUseNativeDialog);
+ fd.show();
+
+ //play it really safe by creating a directory
+ QDir::home().mkdir("_____aaaaaaaaaaaaaaaaaaaaaa");
+
+ QLineEdit *lineEdit = qFindChild<QLineEdit*>(&fd, "fileNameEdit");
+ QVERIFY(lineEdit);
+ QVERIFY(lineEdit->text() == "foo");
+ fd.setDirectory(QDir::home());
+
+ QListView* list = qFindChild<QListView*>(&fd, "listView");
+ QVERIFY(list);
+
+ // saving a file the text shouldn't be cleared
+ fd.setDirectory(QDir::home());
+
+ QTest::qWait(1000);
+#ifdef QT_KEYPAD_NAVIGATION
+ list->setEditFocus(true);
+#endif
+ QTest::keyClick(list, Qt::Key_Down);
+#ifndef Q_WS_MAC
+ QTest::keyClick(list, Qt::Key_Return);
+#else
+ QTest::keyClick(list, Qt::Key_O, Qt::ControlModifier);
+#endif
+
+ QTest::qWait(2000);
+ QVERIFY(fd.directory().absolutePath() != QDir::home().absolutePath());
+ QVERIFY(!lineEdit->text().isEmpty());
+
+ // selecting a dir the text should be cleared so one can just hit ok
+ // and it selects that directory
+ fd.setFileMode(QNonNativeFileDialog::Directory);
+ fd.setDirectory(QDir::home());
+
+ QTest::qWait(1000);
+ QTest::keyClick(list, Qt::Key_Down);
+#ifndef Q_WS_MAC
+ QTest::keyClick(list, Qt::Key_Return);
+#else
+ QTest::keyClick(list, Qt::Key_O, Qt::ControlModifier);
+#endif
+
+ QTest::qWait(2000);
+ QVERIFY(fd.directory().absolutePath() != QDir::home().absolutePath());
+ QVERIFY(lineEdit->text().isEmpty());
+
+ //remove the dir
+ QDir::home().rmdir("_____aaaaaaaaaaaaaaaaaaaaaa");
+}
+
+void tst_QFiledialog::enableChooseButton()
+{
+ QNonNativeFileDialog fd;
+ fd.setFileMode(QFileDialog::Directory);
+ fd.show();
+ QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox*>(&fd, "buttonBox");
+ QPushButton *button = buttonBox->button(QDialogButtonBox::Open);
+ QVERIFY(button);
+ QCOMPARE(button->isEnabled(), true);
+}
+
+QT_BEGIN_NAMESPACE
+typedef QString (*_qt_filedialog_existing_directory_hook)(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options);
+extern Q_GUI_EXPORT _qt_filedialog_existing_directory_hook qt_filedialog_existing_directory_hook;
+QT_END_NAMESPACE
+QString existing(QWidget *, const QString &, const QString &, QFileDialog::Options) {
+ return "dir";
+}
+
+QT_BEGIN_NAMESPACE
+typedef QString (*_qt_filedialog_open_filename_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options);
+extern Q_GUI_EXPORT _qt_filedialog_open_filename_hook qt_filedialog_open_filename_hook;
+QT_END_NAMESPACE
+QString openName(QWidget *, const QString &, const QString &, const QString &, QString *, QFileDialog::Options) {
+ return "openName";
+}
+
+QT_BEGIN_NAMESPACE
+typedef QStringList (*_qt_filedialog_open_filenames_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options);
+extern Q_GUI_EXPORT _qt_filedialog_open_filenames_hook qt_filedialog_open_filenames_hook;
+QT_END_NAMESPACE
+QStringList openNames(QWidget *, const QString &, const QString &, const QString &, QString *, QFileDialog::Options) {
+ return QStringList("openNames");
+}
+
+QT_BEGIN_NAMESPACE
+typedef QString (*_qt_filedialog_save_filename_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options);
+extern Q_GUI_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook;
+QT_END_NAMESPACE
+QString saveName(QWidget *, const QString &, const QString &, const QString &, QString *, QFileDialog::Options) {
+ return "saveName";
+}
+
+
+void tst_QFiledialog::hooks()
+{
+ qt_filedialog_existing_directory_hook = &existing;
+ qt_filedialog_save_filename_hook = &saveName;
+ qt_filedialog_open_filename_hook = &openName;
+ qt_filedialog_open_filenames_hook = &openNames;
+
+ QCOMPARE(QFileDialog::getExistingDirectory(), QString("dir"));
+ QCOMPARE(QFileDialog::getOpenFileName(), QString("openName"));
+ QCOMPARE(QFileDialog::getOpenFileNames(), QStringList("openNames"));
+ QCOMPARE(QFileDialog::getSaveFileName(), QString("saveName"));
+}
+
+// Test case relies on developer build (AUTOTEST_EXPORT).
+#if defined(Q_OS_UNIX) && defined(QT_BUILD_INTERNAL)
+void tst_QFiledialog::tildeExpansion_data()
+{
+ QTest::addColumn<QString>("tildePath");
+ QTest::addColumn<QString>("expandedPath");
+
+ QTest::newRow("empty path") << QString() << QString();
+ QTest::newRow("~") << QString::fromLatin1("~") << QDir::homePath();
+ QTest::newRow("~/some/sub/dir/") << QString::fromLatin1("~/some/sub/dir") << QDir::homePath()
+ + QString::fromLatin1("/some/sub/dir");
+ QString userHome = QString(qgetenv("USER"));
+ userHome.prepend('~');
+ QTest::newRow("current user (~<user> syntax)") << userHome << QDir::homePath();
+ QString invalid = QString::fromLatin1("~thisIsNotAValidUserName");
+ QTest::newRow("invalid user name") << invalid << invalid;
+}
+
+void tst_QFiledialog::tildeExpansion()
+{
+ QFETCH(QString, tildePath);
+ QFETCH(QString, expandedPath);
+
+ QCOMPARE(qt_tildeExpansion(tildePath), expandedPath);
+}
+#endif
+
+QTEST_MAIN(tst_QFiledialog)
+#include "tst_qfiledialog.moc"
diff --git a/tests/auto/widgets/dialogs/qfiledialog2/qfiledialog2.pro b/tests/auto/widgets/dialogs/qfiledialog2/qfiledialog2.pro
new file mode 100644
index 0000000000..a2149c8a39
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfiledialog2/qfiledialog2.pro
@@ -0,0 +1,20 @@
+load(qttest_p4)
+
+QT += widgets widgets-private
+QT += core-private gui-private
+
+SOURCES += tst_qfiledialog2.cpp
+
+wince* {
+ addFiles.files = *.cpp
+ addFiles.path = .
+ filesInDir.files = *.pro
+ filesInDir.path = someDir
+ DEPLOYMENT += addFiles filesInDir
+}
+
+wince* {
+ DEFINES += SRCDIR=\\\"./\\\"
+} else {
+ DEFINES += SRCDIR=\\\"$$PWD/\\\"
+}
diff --git a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp
new file mode 100644
index 0000000000..a2d18eb847
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp
@@ -0,0 +1,1213 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+#include <qcoreapplication.h>
+#include <qdebug.h>
+#include <qfiledialog.h>
+#include <qabstractitemdelegate.h>
+#include <qdirmodel.h>
+#include <qitemdelegate.h>
+#include <qlistview.h>
+#include <qcombobox.h>
+#include <qpushbutton.h>
+#include <qtoolbutton.h>
+#include <qtreeview.h>
+#include <qheaderview.h>
+#include <qcompleter.h>
+#include <qaction.h>
+#include <qdialogbuttonbox.h>
+#include <qsortfilterproxymodel.h>
+#include <qlineedit.h>
+#include <qlayout.h>
+#include "../../../../../src/widgets/dialogs/qsidebar_p.h"
+#include "../../../../../src/widgets/dialogs/qfilesystemmodel_p.h"
+#include "../../../../../src/widgets/dialogs/qfiledialog_p.h"
+
+#include "../../../network-settings.h"
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+#if defined QT_BUILD_INTERNAL
+QT_BEGIN_NAMESPACE
+Q_GUI_EXPORT bool qt_test_isFetchedRoot();
+Q_GUI_EXPORT void qt_test_resetFetchedRoot();
+QT_END_NAMESPACE
+#endif
+
+class QNonNativeFileDialog : public QFileDialog
+{
+ Q_OBJECT
+public:
+ QNonNativeFileDialog(QWidget *parent = 0, const QString &caption = QString(), const QString &directory = QString(), const QString &filter = QString())
+ : QFileDialog(parent, caption, directory, filter)
+ {
+ setOption(QFileDialog::DontUseNativeDialog, true);
+ }
+};
+
+class tst_QFileDialog2 : public QObject
+{
+Q_OBJECT
+
+public:
+ tst_QFileDialog2();
+ virtual ~tst_QFileDialog2();
+
+public slots:
+ void init();
+ void cleanup();
+
+private slots:
+ void listRoot();
+ void heapCorruption();
+ void deleteDirAndFiles();
+ void filter();
+ void showNameFilterDetails();
+ void unc();
+ void emptyUncPath();
+
+ void task178897_minimumSize();
+ void task180459_lastDirectory_data();
+ void task180459_lastDirectory();
+ void task227304_proxyOnFileDialog();
+ void task227930_correctNavigationKeyboardBehavior();
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ void task226366_lowerCaseHardDriveWindows();
+#endif
+ void completionOnLevelAfterRoot();
+ void task233037_selectingDirectory();
+ void task235069_hideOnEscape();
+ void task236402_dontWatchDeletedDir();
+ void task203703_returnProperSeparator();
+ void task228844_ensurePreviousSorting();
+ void task239706_editableFilterCombo();
+ void task218353_relativePaths();
+ void task251321_sideBarHiddenEntries();
+ void task251341_sideBarRemoveEntries();
+ void task254490_selectFileMultipleTimes();
+ void task257579_sideBarWithNonCleanUrls();
+ void task259105_filtersCornerCases();
+
+ void QTBUG4419_lineEditSelectAll();
+ void QTBUG6558_showDirsOnly();
+ void QTBUG4842_selectFilterWithHideNameFilterDetails();
+ void dontShowCompleterOnRoot();
+
+private:
+ QByteArray userSettings;
+};
+
+tst_QFileDialog2::tst_QFileDialog2()
+{
+#if defined(Q_OS_WINCE)
+ qApp->setAutoMaximizeThreshold(-1);
+#endif
+}
+
+tst_QFileDialog2::~tst_QFileDialog2()
+{
+}
+
+void tst_QFileDialog2::init()
+{
+ // Save the developers settings so they don't get mad when their sidebar folders are gone.
+ QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+ settings.beginGroup(QLatin1String("Qt"));
+ userSettings = settings.value(QLatin1String("filedialog")).toByteArray();
+ settings.remove(QLatin1String("filedialog"));
+
+ // populate it with some default settings
+ QNonNativeFileDialog fd;
+#if defined(Q_OS_WINCE)
+ QTest::qWait(1000);
+#endif
+}
+
+void tst_QFileDialog2::cleanup()
+{
+ QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+ settings.beginGroup(QLatin1String("Qt"));
+ settings.setValue(QLatin1String("filedialog"), userSettings);
+}
+
+void tst_QFileDialog2::listRoot()
+{
+#if defined QT_BUILD_INTERNAL
+ QFileInfoGatherer fileInfoGatherer;
+ fileInfoGatherer.start();
+ QTest::qWait(1500);
+ qt_test_resetFetchedRoot();
+ QString dir(QDir::currentPath());
+ QNonNativeFileDialog fd(0, QString(), dir);
+ fd.show();
+ QCOMPARE(qt_test_isFetchedRoot(),false);
+ fd.setDirectory("");
+#ifdef Q_OS_WINCE
+ QTest::qWait(1500);
+#else
+ QTest::qWait(500);
+#endif
+ QCOMPARE(qt_test_isFetchedRoot(),true);
+#endif
+}
+
+void tst_QFileDialog2::heapCorruption()
+{
+ QVector<QNonNativeFileDialog*> dialogs;
+ for (int i=0; i < 10; i++) {
+ QNonNativeFileDialog *f = new QNonNativeFileDialog(NULL);
+ dialogs << f;
+ }
+ qDeleteAll(dialogs);
+}
+
+struct FriendlyQFileDialog : public QNonNativeFileDialog
+{
+ friend class tst_QFileDialog2;
+ Q_DECLARE_PRIVATE(QFileDialog)
+};
+
+
+void tst_QFileDialog2::deleteDirAndFiles()
+{
+#if defined QT_BUILD_INTERNAL
+ QString tempPath = QDir::tempPath() + '/' + "QFileDialogTestDir4FullDelete";
+ QDir dir;
+ QVERIFY(dir.mkpath(tempPath + "/foo"));
+ QVERIFY(dir.mkpath(tempPath + "/foo/B"));
+ QVERIFY(dir.mkpath(tempPath + "/foo/B"));
+ QVERIFY(dir.mkpath(tempPath + "/foo/c"));
+ QVERIFY(dir.mkpath(tempPath + "/bar"));
+ QFile(tempPath + "/foo/a");
+ QTemporaryFile *t;
+ t = new QTemporaryFile(tempPath + "/foo/aXXXXXX");
+ t->setAutoRemove(false);
+ t->open();
+ t->close();
+ delete t;
+
+ t = new QTemporaryFile(tempPath + "/foo/B/yXXXXXX");
+ t->setAutoRemove(false);
+ t->open();
+ t->close();
+ delete t;
+ FriendlyQFileDialog fd;
+ fd.setOption(QFileDialog::DontUseNativeDialog);
+ fd.d_func()->removeDirectory(tempPath);
+ QFileInfo info(tempPath);
+ QTest::qWait(2000);
+ QVERIFY(!info.exists());
+#endif
+}
+
+void tst_QFileDialog2::filter()
+{
+ QNonNativeFileDialog fd;
+ QAction *hiddenAction = qFindChild<QAction*>(&fd, "qt_show_hidden_action");
+ QVERIFY(hiddenAction);
+ QVERIFY(hiddenAction->isEnabled());
+ QVERIFY(!hiddenAction->isChecked());
+ QDir::Filters filter = fd.filter();
+ filter |= QDir::Hidden;
+ fd.setFilter(filter);
+ QVERIFY(hiddenAction->isChecked());
+}
+
+void tst_QFileDialog2::showNameFilterDetails()
+{
+ QNonNativeFileDialog fd;
+ QComboBox *filters = qFindChild<QComboBox*>(&fd, "fileTypeCombo");
+ QVERIFY(filters);
+ QVERIFY(fd.isNameFilterDetailsVisible());
+
+
+ QStringList filterChoices;
+ filterChoices << "Image files (*.png *.xpm *.jpg)"
+ << "Text files (*.txt)"
+ << "Any files (*.*)";
+ fd.setFilters(filterChoices);
+
+ fd.setNameFilterDetailsVisible(false);
+ QCOMPARE(filters->itemText(0), QString("Image files"));
+ QCOMPARE(filters->itemText(1), QString("Text files"));
+ QCOMPARE(filters->itemText(2), QString("Any files"));
+
+ fd.setNameFilterDetailsVisible(true);
+ QCOMPARE(filters->itemText(0), filterChoices.at(0));
+ QCOMPARE(filters->itemText(1), filterChoices.at(1));
+ QCOMPARE(filters->itemText(2), filterChoices.at(2));
+}
+
+void tst_QFileDialog2::unc()
+{
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ // Only test UNC on Windows./
+ QString dir("\\\\" + QtNetworkSettings::winServerName() + "\\testsharewritable");
+#else
+ QString dir(QDir::currentPath());
+#endif
+ QVERIFY(QFile::exists(dir));
+ QNonNativeFileDialog fd(0, QString(), dir);
+ QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
+ QVERIFY(model);
+ QCOMPARE(model->index(fd.directory().absolutePath()), model->index(dir));
+}
+
+void tst_QFileDialog2::emptyUncPath()
+{
+ QNonNativeFileDialog fd;
+ fd.show();
+ QLineEdit *lineEdit = qFindChild<QLineEdit*>(&fd, "fileNameEdit");
+ QVERIFY(lineEdit);
+ // press 'keys' for the input
+ for (int i = 0; i < 3 ; ++i)
+ QTest::keyPress(lineEdit, Qt::Key_Backslash);
+ QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
+ QVERIFY(model);
+}
+
+void tst_QFileDialog2::task178897_minimumSize()
+{
+ QNonNativeFileDialog fd;
+ QSize oldMs = fd.layout()->minimumSize();
+ QStringList history = fd.history();
+ history << QDir::toNativeSeparators("/verylongdirectory/"
+ "aaaaaaaaaabbbbbbbbcccccccccccddddddddddddddeeeeeeeeeeeeffffffffffgggtggggggggghhhhhhhhiiiiiijjjk");
+ fd.setHistory(history);
+ fd.show();
+
+ QSize ms = fd.layout()->minimumSize();
+ QVERIFY(ms.width() <= oldMs.width());
+}
+
+void tst_QFileDialog2::task180459_lastDirectory_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<QString>("directory");
+ QTest::addColumn<bool>("isEnabled");
+ QTest::addColumn<QString>("result");
+
+ QTest::newRow("path+file") << QDir::homePath() + QDir::separator() + "foo"
+ << QDir::homePath() << true
+ << QDir::homePath() + QDir::separator() + "foo" ;
+ QTest::newRow("no path") << ""
+ << QDir::tempPath() << false << QString();
+ QTest::newRow("file") << "foo"
+ << QDir::currentPath() << true
+ << QDir::currentPath() + QDir::separator() + "foo" ;
+ QTest::newRow("path") << QDir::homePath()
+ << QDir::homePath() << false << QString();
+ QTest::newRow("path not existing") << "/usr/bin/foo/bar/foo/foo.txt"
+ << QDir::tempPath() << true
+ << QDir::tempPath() + QDir::separator() + "foo.txt";
+
+}
+
+void tst_QFileDialog2::task180459_lastDirectory()
+{
+ //first visit the temp directory and close the dialog
+ QNonNativeFileDialog *dlg = new QNonNativeFileDialog(0, "", QDir::tempPath());
+ QFileSystemModel *model = qFindChild<QFileSystemModel*>(dlg, "qt_filesystem_model");
+ QVERIFY(model);
+ QCOMPARE(model->index(QDir::tempPath()), model->index(dlg->directory().absolutePath()));
+ delete dlg;
+
+ QFETCH(QString, path);
+ QFETCH(QString, directory);
+ QFETCH(bool, isEnabled);
+ QFETCH(QString, result);
+
+ dlg = new QNonNativeFileDialog(0, "", path);
+ model = qFindChild<QFileSystemModel*>(dlg, "qt_filesystem_model");
+ QVERIFY(model);
+ dlg->setAcceptMode(QFileDialog::AcceptSave);
+ QCOMPARE(model->index(dlg->directory().absolutePath()), model->index(directory));
+
+ QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox*>(dlg, "buttonBox");
+ QPushButton *button = buttonBox->button(QDialogButtonBox::Save);
+ QVERIFY(button);
+ QCOMPARE(button->isEnabled(), isEnabled);
+ if (isEnabled)
+ QCOMPARE(model->index(result), model->index(dlg->selectedFiles().first()));
+
+ delete dlg;
+}
+
+
+
+class FilterDirModel : public QSortFilterProxyModel
+{
+
+public:
+ FilterDirModel(QString root, QObject* parent=0):QSortFilterProxyModel(parent), m_root(root)
+ {}
+ ~FilterDirModel()
+ {};
+
+protected:
+ bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
+ {
+ QModelIndex parentIndex;
+ parentIndex = source_parent;
+
+ QString path;
+ path = parentIndex.child(source_row,0).data(Qt::DisplayRole).toString();
+
+ do {
+ path = parentIndex.data(Qt::DisplayRole).toString() + "/" + path;
+ parentIndex = parentIndex.parent();
+ } while(parentIndex.isValid());
+
+ QFileInfo info(path);
+ if (info.isDir() && (QDir(path) != m_root))
+ return false;
+ return true;
+ }
+
+
+private:
+ QDir m_root;
+
+
+};
+
+class sortProxy : public QSortFilterProxyModel
+{
+public:
+ sortProxy(QObject *parent) : QSortFilterProxyModel(parent)
+ {
+ }
+protected:
+ virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const
+ {
+ QFileSystemModel * const model = qobject_cast<QFileSystemModel *>(sourceModel());
+ const QFileInfo leftInfo(model->fileInfo(left));
+ const QFileInfo rightInfo(model->fileInfo(right));
+
+ if (leftInfo.isDir() == rightInfo.isDir())
+ return(leftInfo.filePath().compare(rightInfo.filePath(),Qt::CaseInsensitive) < 0);
+ else if (leftInfo.isDir())
+ return(false);
+ else
+ return(true);
+ }
+};
+
+class CrashDialog : public QNonNativeFileDialog
+{
+ Q_OBJECT
+
+public:
+ CrashDialog(QWidget *parent, const QString &caption, const
+QString &dir, const QString &filter)
+ : QNonNativeFileDialog(parent, caption, dir, filter)
+ {
+ sortProxy *proxyModel = new sortProxy(this);
+ setProxyModel(proxyModel);
+ }
+};
+
+void tst_QFileDialog2::task227304_proxyOnFileDialog()
+{
+#if defined QT_BUILD_INTERNAL
+ QNonNativeFileDialog fd(0, "", QDir::currentPath(), 0);
+ fd.setProxyModel(new FilterDirModel(QDir::currentPath()));
+ fd.show();
+ QLineEdit *edit = qFindChild<QLineEdit*>(&fd, "fileNameEdit");
+ QTest::qWait(200);
+ QTest::keyClick(edit, Qt::Key_T);
+ QTest::keyClick(edit, Qt::Key_S);
+ QTest::qWait(200);
+ QTest::keyClick(edit->completer()->popup(), Qt::Key_Down);
+
+ CrashDialog *dialog = new CrashDialog(0, QString("crash dialog test"), QDir::homePath(), QString("*") );
+ dialog->setFileMode(QFileDialog::ExistingFile);
+ dialog->show();
+
+ QListView *list = qFindChild<QListView*>(dialog, "listView");
+ QTest::qWait(200);
+ QTest::keyClick(list, Qt::Key_Down);
+ QTest::keyClick(list, Qt::Key_Return);
+ QTest::qWait(200);
+
+ dialog->close();
+ fd.close();
+
+ QNonNativeFileDialog fd2(0, "I should not crash with a proxy", QDir::tempPath(), 0);
+ QSortFilterProxyModel *pm = new QSortFilterProxyModel;
+ fd2.setProxyModel(pm);
+ fd2.show();
+ QSidebar *sidebar = qFindChild<QSidebar*>(&fd2, "sidebar");
+ sidebar->setFocus();
+ sidebar->selectUrl(QUrl::fromLocalFile(QDir::homePath()));
+ QTest::mouseClick(sidebar->viewport(), Qt::LeftButton, 0, sidebar->visualRect(sidebar->model()->index(1, 0)).center());
+ QTest::qWait(250);
+ //We shouldn't crash
+#endif
+}
+
+void tst_QFileDialog2::task227930_correctNavigationKeyboardBehavior()
+{
+ QDir current = QDir::currentPath();
+ current.mkdir("test");
+ current.cd("test");
+ QFile file("test/out.txt");
+ QFile file2("test/out2.txt");
+ QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Text));
+ QVERIFY(file2.open(QIODevice::WriteOnly | QIODevice::Text));
+ current.cdUp();
+ current.mkdir("test2");
+ QNonNativeFileDialog fd;
+ fd.setViewMode(QFileDialog::List);
+ fd.setDirectory(current.absolutePath());
+ fd.show();
+ QListView *list = qFindChild<QListView*>(&fd, "listView");
+ QTest::qWait(200);
+ QTest::keyClick(list, Qt::Key_Down);
+ QTest::keyClick(list, Qt::Key_Return);
+ QTest::qWait(200);
+ QTest::mouseClick(list->viewport(), Qt::LeftButton,0);
+ QTest::keyClick(list, Qt::Key_Down);
+ QTest::keyClick(list, Qt::Key_Backspace);
+ QTest::qWait(200);
+ QTest::keyClick(list, Qt::Key_Down);
+ QTest::keyClick(list, Qt::Key_Down);
+ QTest::keyClick(list, Qt::Key_Return);
+ QTest::qWait(200);
+ QCOMPARE(fd.isVisible(), true);
+ QTest::qWait(200);
+ file.close();
+ file2.close();
+ file.remove();
+ file2.remove();
+ current.rmdir("test");
+ current.rmdir("test2");
+}
+
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+void tst_QFileDialog2::task226366_lowerCaseHardDriveWindows()
+{
+ QNonNativeFileDialog fd;
+ fd.setDirectory(QDir::root().path());
+ fd.show();
+ QLineEdit *edit = qFindChild<QLineEdit*>(&fd, "fileNameEdit");
+ QToolButton *buttonParent = qFindChild<QToolButton*>(&fd, "toParentButton");
+ QTest::qWait(200);
+ QTest::mouseClick(buttonParent, Qt::LeftButton,0,QPoint(0,0));
+ QTest::qWait(2000);
+ QTest::keyClick(edit, Qt::Key_C);
+ QTest::qWait(200);
+ QTest::keyClick(edit->completer()->popup(), Qt::Key_Down);
+ QTest::qWait(200);
+ QCOMPARE(edit->text(), QString("C:/"));
+ QTest::qWait(2000);
+ //i clear my previous selection in the completer
+ QTest::keyClick(edit->completer()->popup(), Qt::Key_Down);
+ edit->clear();
+ QTest::keyClick(edit, (char)(Qt::Key_C | Qt::SHIFT));
+ QTest::qWait(200);
+ QTest::keyClick(edit->completer()->popup(), Qt::Key_Down);
+ QCOMPARE(edit->text(), QString("C:/"));
+}
+#endif
+
+void tst_QFileDialog2::completionOnLevelAfterRoot()
+{
+ QNonNativeFileDialog fd;
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ fd.setDirectory("C:");
+ QDir current = fd.directory();
+ current.mkdir("completionOnLevelAfterRootTest");
+#else
+ fd.setFilter(QDir::Hidden | QDir::AllDirs | QDir::Files | QDir::System);
+ fd.setDirectory("/");
+ QDir etc("/etc");
+ if (!etc.exists())
+ QSKIP("This test requires to have an etc directory under /", SkipAll);
+#endif
+ fd.show();
+ QLineEdit *edit = qFindChild<QLineEdit*>(&fd, "fileNameEdit");
+ QTest::qWait(2000);
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ //I love testlib :D
+ QTest::keyClick(edit, Qt::Key_C);
+ QTest::keyClick(edit, Qt::Key_O);
+ QTest::keyClick(edit, Qt::Key_M);
+ QTest::keyClick(edit, Qt::Key_P);
+ QTest::keyClick(edit, Qt::Key_L);
+#else
+ QTest::keyClick(edit, Qt::Key_E);
+ QTest::keyClick(edit, Qt::Key_T);
+#endif
+ QTest::qWait(200);
+ QTest::keyClick(edit->completer()->popup(), Qt::Key_Down);
+ QTest::qWait(200);
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ QCOMPARE(edit->text(), QString("completionOnLevelAfterRootTest"));
+ current.rmdir("completionOnLevelAfterRootTest");
+#else
+ QTRY_COMPARE(edit->text(), QString("etc"));
+#endif
+}
+
+void tst_QFileDialog2::task233037_selectingDirectory()
+{
+ QDir current = QDir::currentPath();
+ current.mkdir("test");
+ QNonNativeFileDialog fd;
+ fd.setViewMode(QFileDialog::List);
+ fd.setDirectory(current.absolutePath());
+ fd.setAcceptMode( QFileDialog::AcceptSave);
+ fd.show();
+ QListView *list = qFindChild<QListView*>(&fd, "listView");
+ QTest::qWait(3000); // Wait for sort to settle (I need a signal).
+#ifdef QT_KEYPAD_NAVIGATION
+ list->setEditFocus(true);
+#endif
+ QTest::keyClick(list, Qt::Key_Down);
+ QTest::qWait(100);
+ QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox*>(&fd, "buttonBox");
+ QPushButton *button = buttonBox->button(QDialogButtonBox::Save);
+ QVERIFY(button);
+ QCOMPARE(button->isEnabled(), true);
+ current.rmdir("test");
+}
+
+void tst_QFileDialog2::task235069_hideOnEscape()
+{
+ QDir current = QDir::currentPath();
+ QNonNativeFileDialog fd;
+ fd.setViewMode(QFileDialog::List);
+ fd.setDirectory(current.absolutePath());
+ fd.setAcceptMode( QFileDialog::AcceptSave);
+ fd.show();
+ QListView *list = qFindChild<QListView*>(&fd, "listView");
+ list->setFocus();
+ QTest::qWait(200);
+ QTest::keyClick(list, Qt::Key_Escape);
+ QCOMPARE(fd.isVisible(), false);
+ QNonNativeFileDialog fd2;
+ fd2.setDirectory(current.absolutePath());
+ fd2.setAcceptMode( QFileDialog::AcceptSave);
+ fd2.show();
+ QLineEdit *edit = qFindChild<QLineEdit*>(&fd2, "fileNameEdit");
+ QTest::keyClick(edit, Qt::Key_Escape);
+ QCOMPARE(fd2.isVisible(), false);
+}
+
+void tst_QFileDialog2::task236402_dontWatchDeletedDir()
+{
+#if defined QT_BUILD_INTERNAL
+ //THIS TEST SHOULD NOT DISPLAY WARNINGS
+ QDir current = QDir::currentPath();
+ //make sure it is the first on the list
+ current.mkdir("aaaaaaaaaa");
+ FriendlyQFileDialog fd;
+ fd.setViewMode(QFileDialog::List);
+ fd.setDirectory(current.absolutePath());
+ fd.setAcceptMode( QFileDialog::AcceptSave);
+ fd.show();
+ QListView *list = qFindChild<QListView*>(&fd, "listView");
+ list->setFocus();
+ QTest::qWait(200);
+ QTest::keyClick(list, Qt::Key_Return);
+ QTest::qWait(200);
+ QTest::keyClick(list, Qt::Key_Backspace);
+ QTest::keyClick(list, Qt::Key_Down);
+ QTest::qWait(200);
+ fd.d_func()->removeDirectory(current.absolutePath() + "/aaaaaaaaaa/");
+ QTest::qWait(1000);
+#endif
+}
+
+void tst_QFileDialog2::task203703_returnProperSeparator()
+{
+ QDir current = QDir::currentPath();
+ current.mkdir("aaaaaaaaaaaaaaaaaa");
+ QNonNativeFileDialog fd;
+ fd.setDirectory(current.absolutePath());
+ fd.setViewMode(QFileDialog::List);
+ fd.setFileMode(QFileDialog::Directory);
+ fd.show();
+ QTest::qWait(500);
+ QListView *list = qFindChild<QListView*>(&fd, "listView");
+ list->setFocus();
+ QTest::qWait(200);
+ QTest::keyClick(list, Qt::Key_Return);
+ QTest::qWait(1000);
+ QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox*>(&fd, "buttonBox");
+ QPushButton *button = buttonBox->button(QDialogButtonBox::Cancel);
+ QTest::keyClick(button, Qt::Key_Return);
+ QTest::qWait(500);
+ QString result = fd.selectedFiles().first();
+ QVERIFY(result.at(result.count() - 1) != '/');
+ QVERIFY(!result.contains('\\'));
+ current.rmdir("aaaaaaaaaaaaaaaaaa");
+}
+
+void tst_QFileDialog2::task228844_ensurePreviousSorting()
+{
+ QDir current = QDir::currentPath();
+ current.mkdir("aaaaaaaaaaaaaaaaaa");
+ current.cd("aaaaaaaaaaaaaaaaaa");
+ current.mkdir("a");
+ current.mkdir("b");
+ current.mkdir("c");
+ current.mkdir("d");
+ current.mkdir("e");
+ current.mkdir("f");
+ current.mkdir("g");
+ QTemporaryFile *tempFile = new QTemporaryFile(current.absolutePath() + "/rXXXXXX");
+ tempFile->open();
+ current.cdUp();
+
+ QNonNativeFileDialog fd;
+ fd.setDirectory(current.absolutePath());
+ fd.setViewMode(QFileDialog::Detail);
+ fd.show();
+#if defined(Q_OS_WINCE)
+ QTest::qWait(1500);
+#else
+ QTest::qWait(500);
+#endif
+ QTreeView *tree = qFindChild<QTreeView*>(&fd, "treeView");
+ tree->header()->setSortIndicator(3,Qt::DescendingOrder);
+ QTest::qWait(200);
+ QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox*>(&fd, "buttonBox");
+ QPushButton *button = buttonBox->button(QDialogButtonBox::Open);
+ QTest::mouseClick(button, Qt::LeftButton);
+#if defined(Q_OS_WINCE)
+ QTest::qWait(1500);
+#else
+ QTest::qWait(500);
+#endif
+ QNonNativeFileDialog fd2;
+ fd2.setFileMode(QFileDialog::Directory);
+ fd2.restoreState(fd.saveState());
+ current.cd("aaaaaaaaaaaaaaaaaa");
+ fd2.setDirectory(current.absolutePath());
+ fd2.show();
+#if defined(Q_OS_WINCE)
+ QTest::qWait(1500);
+#else
+ QTest::qWait(500);
+#endif
+ QTreeView *tree2 = qFindChild<QTreeView*>(&fd2, "treeView");
+ tree2->setFocus();
+
+ QCOMPARE(tree2->rootIndex().data(QFileSystemModel::FilePathRole).toString(),current.absolutePath());
+
+ QDialogButtonBox *buttonBox2 = qFindChild<QDialogButtonBox*>(&fd2, "buttonBox");
+ QPushButton *button2 = buttonBox2->button(QDialogButtonBox::Open);
+ fd2.selectFile("g");
+ QTest::mouseClick(button2, Qt::LeftButton);
+#if defined(Q_OS_WINCE)
+ QTest::qWait(1500);
+#else
+ QTest::qWait(500);
+#endif
+ QCOMPARE(fd2.selectedFiles().first(), current.absolutePath() + QChar('/') + QLatin1String("g"));
+
+ QNonNativeFileDialog fd3(0, "This is a third file dialog", tempFile->fileName());
+ fd3.restoreState(fd.saveState());
+ fd3.setFileMode(QFileDialog::Directory);
+ fd3.show();
+#if defined(Q_OS_WINCE)
+ QTest::qWait(1500);
+#else
+ QTest::qWait(500);
+#endif
+ QTreeView *tree3 = qFindChild<QTreeView*>(&fd3, "treeView");
+ tree3->setFocus();
+
+ QCOMPARE(tree3->rootIndex().data(QFileSystemModel::FilePathRole).toString(), current.absolutePath());
+
+ QDialogButtonBox *buttonBox3 = qFindChild<QDialogButtonBox*>(&fd3, "buttonBox");
+ QPushButton *button3 = buttonBox3->button(QDialogButtonBox::Open);
+ QTest::mouseClick(button3, Qt::LeftButton);
+#if defined(Q_OS_WINCE)
+ QTest::qWait(1500);
+#else
+ QTest::qWait(500);
+#endif
+ QCOMPARE(fd3.selectedFiles().first(), tempFile->fileName());
+
+ current.cd("aaaaaaaaaaaaaaaaaa");
+ current.rmdir("a");
+ current.rmdir("b");
+ current.rmdir("c");
+ current.rmdir("d");
+ current.rmdir("e");
+ current.rmdir("f");
+ current.rmdir("g");
+ tempFile->close();
+ delete tempFile;
+ current.cdUp();
+ current.rmdir("aaaaaaaaaaaaaaaaaa");
+}
+
+
+void tst_QFileDialog2::task239706_editableFilterCombo()
+{
+ QNonNativeFileDialog d;
+ d.setNameFilter("*.cpp *.h");
+
+ d.show();
+ QTest::qWait(500);
+
+ QList<QComboBox *> comboList = d.findChildren<QComboBox *>();
+ QComboBox *filterCombo = 0;
+ foreach (QComboBox *combo, comboList) {
+ if (combo->objectName() == QString("fileTypeCombo")) {
+ filterCombo = combo;
+ break;
+ }
+ }
+ QVERIFY(filterCombo);
+ filterCombo->setEditable(true);
+ QTest::mouseClick(filterCombo, Qt::LeftButton);
+ QTest::keyPress(filterCombo, Qt::Key_X);
+ QTest::keyPress(filterCombo, Qt::Key_Enter); // should not trigger assertion failure
+}
+
+void tst_QFileDialog2::task218353_relativePaths()
+{
+ QDir appDir = QDir::current();
+ QVERIFY(appDir.cdUp() != false);
+ QNonNativeFileDialog d(0, "TestDialog", "..");
+ QCOMPARE(d.directory().absolutePath(), appDir.absolutePath());
+
+ d.setDirectory(appDir.absolutePath() + QLatin1String("/non-existing-directory/../another-non-existing-dir/../"));
+ QCOMPARE(d.directory().absolutePath(), appDir.absolutePath());
+
+ QDir::current().mkdir("test");
+ appDir = QDir::current();
+ d.setDirectory(appDir.absolutePath() + QLatin1String("/test/../test/../"));
+ QCOMPARE(d.directory().absolutePath(), appDir.absolutePath());
+ appDir.rmdir("test");
+}
+
+void tst_QFileDialog2::task251321_sideBarHiddenEntries()
+{
+#if defined QT_BUILD_INTERNAL
+ QNonNativeFileDialog fd;
+
+ QDir current = QDir::currentPath();
+ current.mkdir(".hidden");
+ QDir hiddenDir = QDir(".hidden");
+ hiddenDir.mkdir("subdir");
+ QDir hiddenSubDir = QDir(".hidden/subdir");
+ hiddenSubDir.mkdir("happy");
+ hiddenSubDir.mkdir("happy2");
+
+ QList<QUrl> urls;
+ urls << QUrl::fromLocalFile(hiddenSubDir.absolutePath());
+ fd.setSidebarUrls(urls);
+ fd.show();
+ QTest::qWait(250);
+
+ QSidebar *sidebar = qFindChild<QSidebar*>(&fd, "sidebar");
+ sidebar->setFocus();
+ sidebar->selectUrl(QUrl::fromLocalFile(hiddenSubDir.absolutePath()));
+ QTest::mouseClick(sidebar->viewport(), Qt::LeftButton, 0, sidebar->visualRect(sidebar->model()->index(0, 0)).center());
+ // give the background processes more time on windows mobile
+#ifdef Q_OS_WINCE
+ QTest::qWait(1000);
+#else
+ QTest::qWait(250);
+#endif
+
+ QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
+ QCOMPARE(model->rowCount(model->index(hiddenSubDir.absolutePath())), 2);
+
+ hiddenSubDir.rmdir("happy2");
+ hiddenSubDir.rmdir("happy");
+ hiddenDir.rmdir("subdir");
+ current.rmdir(".hidden");
+#endif
+}
+
+#if defined QT_BUILD_INTERNAL
+class MyQSideBar : public QSidebar
+{
+public :
+ MyQSideBar(QWidget *parent = 0) : QSidebar(parent)
+ {}
+
+ void removeSelection() {
+ QList<QModelIndex> idxs = selectionModel()->selectedIndexes();
+ QList<QPersistentModelIndex> indexes;
+ for (int i = 0; i < idxs.count(); i++)
+ indexes.append(idxs.at(i));
+
+ for (int i = 0; i < indexes.count(); ++i)
+ if (!indexes.at(i).data(Qt::UserRole + 1).toUrl().path().isEmpty())
+ model()->removeRow(indexes.at(i).row());
+ }
+};
+#endif
+
+void tst_QFileDialog2::task251341_sideBarRemoveEntries()
+{
+#if defined QT_BUILD_INTERNAL
+ QNonNativeFileDialog fd;
+
+ QDir current = QDir::currentPath();
+ current.mkdir("testDir");
+ QDir testSubDir = QDir("testDir");
+
+ QList<QUrl> urls;
+ urls << QUrl::fromLocalFile(testSubDir.absolutePath());
+ urls << QUrl::fromLocalFile("NotFound");
+ fd.setSidebarUrls(urls);
+ fd.show();
+ QTest::qWait(250);
+
+ QSidebar *sidebar = qFindChild<QSidebar*>(&fd, "sidebar");
+ sidebar->setFocus();
+ //We enter in the first bookmark
+ sidebar->selectUrl(QUrl::fromLocalFile(testSubDir.absolutePath()));
+ QTest::mouseClick(sidebar->viewport(), Qt::LeftButton, 0, sidebar->visualRect(sidebar->model()->index(0, 0)).center());
+ QTest::qWait(250);
+
+ QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
+ //There is no file
+ QCOMPARE(model->rowCount(model->index(testSubDir.absolutePath())), 0);
+ //Icon is not enabled QUrlModel::EnabledRole
+ QVariant value = sidebar->model()->index(0, 0).data(Qt::UserRole + 2);
+ QCOMPARE(qvariant_cast<bool>(value), true);
+
+ sidebar->setFocus();
+ //We enter in the second bookmark which is invalid
+ sidebar->selectUrl(QUrl::fromLocalFile("NotFound"));
+ QTest::mouseClick(sidebar->viewport(), Qt::LeftButton, 0, sidebar->visualRect(sidebar->model()->index(1, 0)).center());
+ QTest::qWait(250);
+
+ //We fallback to root because the entry in the bookmark is invalid
+ QCOMPARE(model->rowCount(model->index("NotFound")), model->rowCount(model->index(model->rootPath())));
+ //Icon is not enabled QUrlModel::EnabledRole
+ value = sidebar->model()->index(1, 0).data(Qt::UserRole + 2);
+ QCOMPARE(qvariant_cast<bool>(value), false);
+
+ MyQSideBar mySideBar;
+ mySideBar.init(model, urls);
+ mySideBar.show();
+ mySideBar.selectUrl(QUrl::fromLocalFile(testSubDir.absolutePath()));
+ QTest::qWait(1000);
+ mySideBar.removeSelection();
+
+ //We remove the first entry
+ QList<QUrl> expected;
+ expected << QUrl::fromLocalFile("NotFound");
+ QCOMPARE(mySideBar.urls(), expected);
+
+ mySideBar.selectUrl(QUrl::fromLocalFile("NotFound"));
+ mySideBar.removeSelection();
+
+ //We remove the second entry
+ expected.clear();
+ QCOMPARE(mySideBar.urls(), expected);
+
+ current.rmdir("testDir");
+#endif
+}
+
+void tst_QFileDialog2::task254490_selectFileMultipleTimes()
+{
+ QString tempPath = QDir::tempPath();
+ QTemporaryFile *t;
+ t = new QTemporaryFile;
+ t->open();
+ QNonNativeFileDialog fd(0, "TestFileDialog");
+
+ fd.setDirectory(tempPath);
+ fd.setViewMode(QFileDialog::List);
+ fd.setAcceptMode(QFileDialog::AcceptSave);
+ fd.setFileMode(QFileDialog::AnyFile);
+
+ //This should select the file in the QFileDialog
+ fd.selectFile(t->fileName());
+
+ //This should clear the selection and write it into the filename line edit
+ fd.selectFile("new_file.txt");
+
+ fd.show();
+ QTest::qWait(250);
+
+ QLineEdit *lineEdit = qFindChild<QLineEdit*>(&fd, "fileNameEdit");
+ QVERIFY(lineEdit);
+ QCOMPARE(lineEdit->text(),QLatin1String("new_file.txt"));
+ QListView *list = qFindChild<QListView*>(&fd, "listView");
+ QVERIFY(list);
+ QCOMPARE(list->selectionModel()->selectedRows(0).count(), 0);
+
+ t->deleteLater();
+}
+
+void tst_QFileDialog2::task257579_sideBarWithNonCleanUrls()
+{
+#if defined QT_BUILD_INTERNAL
+ QDir tempDir = QDir::temp();
+ QLatin1String dirname("autotest_task257579");
+ tempDir.rmdir(dirname); //makes sure it doesn't exist any more
+ QVERIFY(tempDir.mkdir(dirname));
+ QString url = QString::fromLatin1("%1/%2/..").arg(tempDir.absolutePath()).arg(dirname);
+ QNonNativeFileDialog fd;
+ fd.setSidebarUrls(QList<QUrl>() << QUrl::fromLocalFile(url));
+ QSidebar *sidebar = qFindChild<QSidebar*>(&fd, "sidebar");
+ QCOMPARE(sidebar->urls().count(), 1);
+ QVERIFY(sidebar->urls().first().toLocalFile() != url);
+ QCOMPARE(sidebar->urls().first().toLocalFile(), QDir::cleanPath(url));
+
+#ifdef Q_OS_WIN
+ QCOMPARE(sidebar->model()->index(0,0).data().toString().toLower(), tempDir.dirName().toLower());
+#else
+ QCOMPARE(sidebar->model()->index(0,0).data().toString(), tempDir.dirName());
+#endif
+
+ //all tests are finished, we can remove the temporary dir
+ QVERIFY(tempDir.rmdir(dirname));
+#endif
+}
+
+void tst_QFileDialog2::task259105_filtersCornerCases()
+{
+ QNonNativeFileDialog fd(0, "TestFileDialog");
+ fd.setNameFilter(QLatin1String("All Files! (*);;Text Files (*.txt)"));
+ fd.setOption(QFileDialog::HideNameFilterDetails, true);
+ fd.show();
+ QTest::qWait(250);
+
+ //Extensions are hidden
+ QComboBox *filters = qFindChild<QComboBox*>(&fd, "fileTypeCombo");
+ QVERIFY(filters);
+ QCOMPARE(filters->currentText(), QLatin1String("All Files!"));
+ filters->setCurrentIndex(1);
+ QCOMPARE(filters->currentText(), QLatin1String("Text Files"));
+
+ //We should have the full names
+ fd.setOption(QFileDialog::HideNameFilterDetails, false);
+ QTest::qWait(250);
+ filters->setCurrentIndex(0);
+ QCOMPARE(filters->currentText(), QLatin1String("All Files! (*)"));
+ filters->setCurrentIndex(1);
+ QCOMPARE(filters->currentText(), QLatin1String("Text Files (*.txt)"));
+
+ //Corner case undocumented of the task
+ fd.setNameFilter(QLatin1String("\352 (I like cheese) All Files! (*);;Text Files (*.txt)"));
+ QCOMPARE(filters->currentText(), QLatin1String("\352 (I like cheese) All Files! (*)"));
+ filters->setCurrentIndex(1);
+ QCOMPARE(filters->currentText(), QLatin1String("Text Files (*.txt)"));
+
+ fd.setOption(QFileDialog::HideNameFilterDetails, true);
+ filters->setCurrentIndex(0);
+ QTest::qWait(500);
+ QCOMPARE(filters->currentText(), QLatin1String("\352 (I like cheese) All Files!"));
+ filters->setCurrentIndex(1);
+ QCOMPARE(filters->currentText(), QLatin1String("Text Files"));
+
+ fd.setOption(QFileDialog::HideNameFilterDetails, true);
+ filters->setCurrentIndex(0);
+ QTest::qWait(500);
+ QCOMPARE(filters->currentText(), QLatin1String("\352 (I like cheese) All Files!"));
+ filters->setCurrentIndex(1);
+ QCOMPARE(filters->currentText(), QLatin1String("Text Files"));
+}
+
+void tst_QFileDialog2::QTBUG4419_lineEditSelectAll()
+{
+ QString tempPath = QDir::tempPath();
+ QTemporaryFile *t;
+ t = new QTemporaryFile;
+ t->open();
+ QNonNativeFileDialog fd(0, "TestFileDialog", t->fileName());
+
+ fd.setDirectory(tempPath);
+ fd.setViewMode(QFileDialog::List);
+ fd.setAcceptMode(QFileDialog::AcceptSave);
+ fd.setFileMode(QFileDialog::AnyFile);
+
+ fd.show();
+ QApplication::setActiveWindow(&fd);
+ QTest::qWaitForWindowShown(&fd);
+ QTRY_COMPARE(fd.isVisible(), true);
+ QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget*>(&fd));
+
+ QTest::qWait(250);
+ QLineEdit *lineEdit = qFindChild<QLineEdit*>(&fd, "fileNameEdit");
+
+ QCOMPARE(tempPath + QChar('/') + lineEdit->text(), t->fileName());
+ QCOMPARE(tempPath + QChar('/') + lineEdit->selectedText(), t->fileName());
+}
+
+void tst_QFileDialog2::QTBUG6558_showDirsOnly()
+{
+ const QString tempPath = QDir::tempPath();
+ QDir dirTemp(tempPath);
+ const QString tempName = QLatin1String("showDirsOnly.") + QString::number(qrand());
+ dirTemp.mkdir(tempName);
+ dirTemp.cd(tempName);
+ QTRY_VERIFY(dirTemp.exists());
+
+ const QString dirPath = dirTemp.absolutePath();
+ QDir dir(dirPath);
+
+ //We create two dirs
+ dir.mkdir("a");
+ dir.mkdir("b");
+
+ //Create a file
+ QFile tempFile(dirPath + "/plop.txt");
+ tempFile.open(QIODevice::WriteOnly | QIODevice::Text);
+ QTextStream out(&tempFile);
+ out << "The magic number is: " << 49 << "\n";
+ tempFile.close();
+
+ QNonNativeFileDialog fd(0, "TestFileDialog");
+
+ fd.setDirectory(dir.absolutePath());
+ fd.setViewMode(QFileDialog::List);
+ fd.setAcceptMode(QFileDialog::AcceptSave);
+ fd.setOption(QFileDialog::ShowDirsOnly, true);
+ fd.show();
+
+ QApplication::setActiveWindow(&fd);
+ QTest::qWaitForWindowShown(&fd);
+ QTRY_COMPARE(fd.isVisible(), true);
+ QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget*>(&fd));
+
+ QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
+ QTRY_COMPARE(model->rowCount(model->index(dir.absolutePath())), 2);
+
+ fd.setOption(QFileDialog::ShowDirsOnly, false);
+ QTRY_COMPARE(model->rowCount(model->index(dir.absolutePath())), 3);
+
+ fd.setOption(QFileDialog::ShowDirsOnly, true);
+ QTRY_COMPARE(model->rowCount(model->index(dir.absolutePath())), 2);
+
+ fd.setFileMode(QFileDialog::DirectoryOnly);
+ QTRY_COMPARE(model->rowCount(model->index(dir.absolutePath())), 2);
+ QTRY_COMPARE(bool(fd.options() & QFileDialog::ShowDirsOnly), true);
+
+ fd.setFileMode(QFileDialog::AnyFile);
+ QTRY_COMPARE(model->rowCount(model->index(dir.absolutePath())), 3);
+ QTRY_COMPARE(bool(fd.options() & QFileDialog::ShowDirsOnly), false);
+
+ fd.setDirectory(QDir::homePath());
+
+ //We remove the dirs
+ dir.rmdir("a");
+ dir.rmdir("b");
+
+ //we delete the file
+ tempFile.remove();
+
+ dirTemp.cdUp();
+ dirTemp.rmdir(tempName);
+}
+
+void tst_QFileDialog2::QTBUG4842_selectFilterWithHideNameFilterDetails()
+{
+ QStringList filtersStr;
+ filtersStr << "Images (*.png *.xpm *.jpg)" << "Text files (*.txt)" << "XML files (*.xml)";
+ QString chosenFilterString("Text files (*.txt)");
+
+ QNonNativeFileDialog fd(0, "TestFileDialog");
+ fd.setAcceptMode(QFileDialog::AcceptSave);
+ fd.setOption(QFileDialog::HideNameFilterDetails, true);
+ fd.setNameFilters(filtersStr);
+ fd.selectNameFilter(chosenFilterString);
+ fd.show();
+
+ QApplication::setActiveWindow(&fd);
+ QTest::qWaitForWindowShown(&fd);
+ QTRY_COMPARE(fd.isVisible(), true);
+ QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget*>(&fd));
+
+ QComboBox *filters = qFindChild<QComboBox*>(&fd, "fileTypeCombo");
+ //We compare the current combobox text with the stripped version
+ QCOMPARE(filters->currentText(), QString("Text files"));
+
+ QNonNativeFileDialog fd2(0, "TestFileDialog");
+ fd2.setAcceptMode(QFileDialog::AcceptSave);
+ fd2.setOption(QFileDialog::HideNameFilterDetails, false);
+ fd2.setNameFilters(filtersStr);
+ fd2.selectNameFilter(chosenFilterString);
+ fd2.show();
+
+ QApplication::setActiveWindow(&fd2);
+ QTest::qWaitForWindowShown(&fd2);
+ QTRY_COMPARE(fd2.isVisible(), true);
+ QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget*>(&fd2));
+
+ QComboBox *filters2 = qFindChild<QComboBox*>(&fd2, "fileTypeCombo");
+ //We compare the current combobox text with the non stripped version
+ QCOMPARE(filters2->currentText(), chosenFilterString);
+
+}
+
+void tst_QFileDialog2::dontShowCompleterOnRoot()
+{
+ QNonNativeFileDialog fd(0, "TestFileDialog");
+ fd.setAcceptMode(QFileDialog::AcceptSave);
+ fd.show();
+
+ QApplication::setActiveWindow(&fd);
+ QTest::qWaitForWindowShown(&fd);
+ QTRY_COMPARE(fd.isVisible(), true);
+ QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget*>(&fd));
+
+ fd.setDirectory("");
+ QLineEdit *lineEdit = qFindChild<QLineEdit*>(&fd, "fileNameEdit");
+ QTRY_VERIFY(lineEdit->text().isEmpty());
+
+ //The gatherer thread will then return the result
+ QApplication::processEvents();
+
+ QTRY_VERIFY(lineEdit->completer()->popup()->isHidden());
+}
+
+QTEST_MAIN(tst_QFileDialog2)
+#include "tst_qfiledialog2.moc"
diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/.gitignore b/tests/auto/widgets/dialogs/qfilesystemmodel/.gitignore
new file mode 100644
index 0000000000..9804e5a3d7
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfilesystemmodel/.gitignore
@@ -0,0 +1 @@
+tst_qfilesystemmodel
diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/qfilesystemmodel.pro b/tests/auto/widgets/dialogs/qfilesystemmodel/qfilesystemmodel.pro
new file mode 100644
index 0000000000..a7d042ce5e
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfilesystemmodel/qfilesystemmodel.pro
@@ -0,0 +1,7 @@
+CONFIG += qttest_p4
+
+QT += widgets widgets-private
+QT += core-private gui
+
+SOURCES += tst_qfilesystemmodel.cpp
+TARGET = tst_qfilesystemmodel
diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp
new file mode 100644
index 0000000000..26fa58e649
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp
@@ -0,0 +1,1046 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#ifdef QT_BUILD_INTERNAL
+#include "../../../src/widgets/dialogs/qfilesystemmodel_p.h"
+#endif
+#include <QFileSystemModel>
+#include <QFileIconProvider>
+#include <QTreeView>
+#include <QHeaderView>
+#include <QTime>
+#include <QStyle>
+#include <QtGlobal>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+#define WAITTIME 1000
+
+// Will try to wait for the condition while allowing event processing
+// for a maximum of 5 seconds.
+#define TRY_WAIT(expr) \
+ do { \
+ const int step = 50; \
+ for (int __i = 0; __i < 5000 && !(expr); __i+=step) { \
+ QTest::qWait(step); \
+ } \
+ } while(0)
+
+class tst_QFileSystemModel : public QObject {
+ Q_OBJECT
+
+public:
+ tst_QFileSystemModel();
+ virtual ~tst_QFileSystemModel();
+
+public Q_SLOTS:
+ void init();
+ void cleanup();
+
+private slots:
+ void indexPath();
+
+ void rootPath();
+ void naturalCompare_data();
+ void naturalCompare();
+ void readOnly();
+ void iconProvider();
+
+ void rowCount();
+
+ void rowsInserted_data();
+ void rowsInserted();
+
+ void rowsRemoved_data();
+ void rowsRemoved();
+
+ void dataChanged_data();
+ void dataChanged();
+
+ void filters_data();
+ void filters();
+
+ void nameFilters();
+
+ void setData_data();
+ void setData();
+
+ void sort_data();
+ void sort();
+
+ void mkdir();
+
+ void caseSensitivity();
+
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ void Win32LongFileName();
+#endif
+
+ void drives_data();
+ void drives();
+ void dirsBeforeFiles();
+
+ void roleNames_data();
+ void roleNames();
+
+protected:
+ bool createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount = 0, const QStringList &intial_dirs = QStringList(), const QString &baseDir = QDir::temp().absolutePath());
+
+private:
+ QFileSystemModel *model;
+ QString flatDirTestPath;
+};
+
+tst_QFileSystemModel::tst_QFileSystemModel() : model(0)
+{
+ qRegisterMetaType<QModelIndex>("QModelIndex");
+
+ QTime midnight(0, 0, 0);
+ qsrand(midnight.secsTo(QTime::currentTime()));
+ // generating unique temporary directory name
+ flatDirTestPath = QDir::temp().path() + '/' + QString("flatdirtest.") + QString::number(qrand());
+}
+
+tst_QFileSystemModel::~tst_QFileSystemModel()
+{
+ QString tmp = flatDirTestPath;
+ QDir dir(tmp);
+ if (dir.exists() && !dir.rmdir(tmp))
+ qWarning("failed to remove tmp dir %s", dir.dirName().toAscii().data());
+}
+
+void tst_QFileSystemModel::init()
+{
+ cleanup();
+ QCOMPARE(model, (QFileSystemModel*)0);
+ model = new QFileSystemModel;
+}
+
+void tst_QFileSystemModel::cleanup()
+{
+ delete model;
+ model = 0;
+ QString tmp = flatDirTestPath;
+ QDir dir(tmp);
+ if (dir.exists(tmp)) {
+ QStringList list = dir.entryList(QDir::AllEntries | QDir::System | QDir::Hidden | QDir::NoDotAndDotDot);
+ for (int i = 0; i < list.count(); ++i) {
+ QFileInfo fi(dir.path() + '/' + list.at(i));
+ if (fi.exists() && fi.isFile()) {
+ QFile p(fi.absoluteFilePath());
+ p.setPermissions(QFile::ReadUser | QFile::ReadOwner | QFile::ExeOwner | QFile::ExeUser | QFile::WriteUser | QFile::WriteOwner | QFile::WriteOther);
+ QFile dead(dir.path() + '/' + list.at(i));
+ dead.remove();
+ }
+ if (fi.exists() && fi.isDir())
+ QVERIFY(dir.rmdir(list.at(i)));
+ }
+ list = dir.entryList(QDir::AllEntries | QDir::System | QDir::Hidden | QDir::NoDotAndDotDot);
+ QVERIFY(list.count() == 0);
+ }
+}
+
+void tst_QFileSystemModel::indexPath()
+{
+#if !defined(Q_OS_WIN)
+ int depth = QDir::currentPath().count('/');
+ model->setRootPath(QDir::currentPath());
+ QTest::qWait(WAITTIME);
+ QString backPath;
+ for (int i = 0; i <= depth * 2 + 1; ++i) {
+ backPath += "../";
+ QModelIndex idx = model->index(backPath);
+ QVERIFY(i != depth - 1 ? idx.isValid() : !idx.isValid());
+ }
+ QTest::qWait(WAITTIME * 3);
+ qApp->processEvents();
+#endif
+}
+
+void tst_QFileSystemModel::rootPath()
+{
+ QCOMPARE(model->rootPath(), QString(QDir().path()));
+
+ QSignalSpy rootChanged(model, SIGNAL(rootPathChanged(const QString &)));
+ QModelIndex root = model->setRootPath(model->rootPath());
+ root = model->setRootPath("this directory shouldn't exist");
+ QCOMPARE(rootChanged.count(), 0);
+
+ QString oldRootPath = model->rootPath();
+ root = model->setRootPath(QDir::homePath());
+
+ QTRY_VERIFY(model->rowCount(root) >= 0);
+ QCOMPARE(model->rootPath(), QString(QDir::homePath()));
+ QCOMPARE(rootChanged.count(), oldRootPath == model->rootPath() ? 0 : 1);
+ QCOMPARE(model->rootDirectory().absolutePath(), QDir::homePath());
+
+ model->setRootPath(QDir::rootPath());
+ int oldCount = rootChanged.count();
+ oldRootPath = model->rootPath();
+ root = model->setRootPath(QDir::homePath() + QLatin1String("/."));
+ QTRY_VERIFY(model->rowCount(root) >= 0);
+ QCOMPARE(model->rootPath(), QDir::homePath());
+ QCOMPARE(rootChanged.count(), oldRootPath == model->rootPath() ? oldCount : oldCount + 1);
+ QCOMPARE(model->rootDirectory().absolutePath(), QDir::homePath());
+
+ QDir newdir = QDir::home();
+ if (newdir.cdUp()) {
+ oldCount = rootChanged.count();
+ oldRootPath = model->rootPath();
+ root = model->setRootPath(QDir::homePath() + QLatin1String("/.."));
+ QTRY_VERIFY(model->rowCount(root) >= 0);
+ QCOMPARE(model->rootPath(), newdir.path());
+ QCOMPARE(rootChanged.count(), oldCount + 1);
+ QCOMPARE(model->rootDirectory().absolutePath(), newdir.path());
+ }
+}
+
+void tst_QFileSystemModel::naturalCompare_data()
+{
+ QTest::addColumn<QString>("s1");
+ QTest::addColumn<QString>("s2");
+ QTest::addColumn<int>("caseSensitive");
+ QTest::addColumn<int>("result");
+ QTest::addColumn<int>("swap");
+ for (int j = 0; j < 4; ++j) { // <- set a prefix and a postfix string (not numbers)
+ QString prefix = (j == 0 || j == 1) ? "b" : "";
+ QString postfix = (j == 1 || j == 2) ? "y" : "";
+
+ for (int k = 0; k < 3; ++k) { // <- make 0 not a special case
+ QString num = QString("%1").arg(k);
+ QString nump = QString("%1").arg(k + 1);
+ for (int i = 10; i < 12; ++i) { // <- swap s1 and s2 and reverse the result
+ QTest::newRow("basic") << prefix + "0" + postfix << prefix + "0" + postfix << int(Qt::CaseInsensitive) << 0;
+
+ // s1 should always be less then s2
+ QTest::newRow("just text") << prefix + "fred" + postfix << prefix + "jane" + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("just numbers") << prefix + num + postfix << prefix + "9" + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("zero") << prefix + num + postfix << prefix + "0" + nump + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("space b") << prefix + num + postfix << prefix + " " + nump + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("space a") << prefix + num + postfix << prefix + nump + " " + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("tab b") << prefix + num + postfix << prefix + " " + nump + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("tab a") << prefix + num + postfix << prefix + nump + " " + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("10 vs 2") << prefix + num + postfix << prefix + "10" + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("diff len") << prefix + num + postfix << prefix + nump + postfix + "x" << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("01 before 1") << prefix + "0" + num + postfix << prefix + nump + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("mul nums 2nd") << prefix + "1-" + num + postfix << prefix + "1-" + nump + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("mul nums 2nd") << prefix + "10-" + num + postfix<< prefix + "10-10" + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("mul nums 2nd") << prefix + "10-0"+ num + postfix<< prefix + "10-10" + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("mul nums 2nd") << prefix + "10-" + num + postfix<< prefix + "10-010" + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("mul nums big") << prefix + "10-" + num + postfix<< prefix + "20-0" + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("mul nums big") << prefix + "2-" + num + postfix << prefix + "10-0" + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("mul alphabet") << prefix + num + "-a" + postfix << prefix + num + "-c" + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("mul alphabet2")<< prefix + num + "-a9" + postfix<< prefix + num + "-c0" + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("mul nums w\\0")<< prefix + num + "-"+ num + postfix<< prefix + num+"-0"+nump + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("num first") << prefix + num + postfix << prefix + "a" + postfix << int(Qt::CaseInsensitive) << i;
+ }
+ }
+ }
+}
+
+void tst_QFileSystemModel::naturalCompare()
+{
+#ifdef QT_BUILD_INTERNAL
+ QFETCH(QString, s1);
+ QFETCH(QString, s2);
+ QFETCH(int, caseSensitive);
+ QFETCH(int, result);
+
+ if (result == 10)
+ QCOMPARE(QFileSystemModelPrivate::naturalCompare(s1, s2, Qt::CaseSensitivity(caseSensitive)), -1);
+ else
+ if (result == 11)
+ QCOMPARE(QFileSystemModelPrivate::naturalCompare(s2, s1, Qt::CaseSensitivity(caseSensitive)), 1);
+ else
+ QCOMPARE(QFileSystemModelPrivate::naturalCompare(s2, s1, Qt::CaseSensitivity(caseSensitive)), result);
+#if defined(Q_OS_WINCE)
+ // On Windows CE we need to wait after each test, otherwise no new threads can be
+ // created. The scheduler takes its time to recognize ended threads.
+ QTest::qWait(300);
+#endif
+#endif
+}
+
+void tst_QFileSystemModel::readOnly()
+{
+ QCOMPARE(model->isReadOnly(), true);
+ QTemporaryFile file;
+ file.open();
+ QModelIndex root = model->setRootPath(QDir::tempPath());
+
+ QTRY_VERIFY(model->rowCount(root) > 0);
+ QVERIFY(!(model->flags(model->index(file.fileName())) & Qt::ItemIsEditable));
+ model->setReadOnly(false);
+ QCOMPARE(model->isReadOnly(), false);
+ QVERIFY(model->flags(model->index(file.fileName())) & Qt::ItemIsEditable);
+}
+
+class CustomFileIconProvider : public QFileIconProvider
+{
+public:
+ CustomFileIconProvider() : QFileIconProvider() {
+ mb = qApp->style()->standardIcon(QStyle::SP_MessageBoxCritical);
+ dvd = qApp->style()->standardIcon(QStyle::SP_DriveDVDIcon);
+ }
+
+ virtual QIcon icon(const QFileInfo &info) const
+ {
+ if (info.isDir())
+ return mb;
+
+ return QFileIconProvider::icon(info);
+ }
+ virtual QIcon icon(IconType type) const
+ {
+ if (type == QFileIconProvider::Folder)
+ return dvd;
+
+ return QFileIconProvider::icon(type);
+ }
+private:
+ QIcon mb;
+ QIcon dvd;
+};
+
+void tst_QFileSystemModel::iconProvider()
+{
+ QVERIFY(model->iconProvider());
+ QFileIconProvider *p = new QFileIconProvider();
+ model->setIconProvider(p);
+ QCOMPARE(model->iconProvider(), p);
+ model->setIconProvider(0);
+ delete p;
+
+ QFileSystemModel *myModel = new QFileSystemModel();
+ myModel->setRootPath(QDir::homePath());
+ //Let's wait to populate the model
+ QTest::qWait(250);
+ //We change the provider, icons must me updated
+ CustomFileIconProvider *custom = new CustomFileIconProvider();
+ myModel->setIconProvider(custom);
+
+ QPixmap mb = qApp->style()->standardIcon(QStyle::SP_MessageBoxCritical).pixmap(50, 50);
+ QCOMPARE(myModel->fileIcon(myModel->index(QDir::homePath())).pixmap(50, 50), mb);
+ delete myModel;
+ delete custom;
+}
+
+bool tst_QFileSystemModel::createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount, const QStringList &initial_dirs, const QString &dir)
+{
+ QDir baseDir(dir);
+ if (!baseDir.exists(test_path)) {
+ if (!baseDir.mkdir(test_path) && false) {
+ qDebug() << "failed to create dir" << test_path;
+ return false;
+ }
+ }
+ //qDebug() << (model->rowCount(model->index(test_path))) << existingFileCount << initial_files;
+ TRY_WAIT((model->rowCount(model->index(test_path)) == existingFileCount));
+ for (int i = 0; i < initial_dirs.count(); ++i) {
+ QDir dir(test_path);
+ if (!dir.exists()) {
+ qWarning() << "error" << test_path << "doesn't exists";
+ return false;
+ }
+ if(!dir.mkdir(initial_dirs.at(i))) {
+ qWarning() << "error" << "failed to make" << initial_dirs.at(i);
+ return false;
+ }
+ //qDebug() << test_path + '/' + initial_dirs.at(i) << (QFile::exists(test_path + '/' + initial_dirs.at(i)));
+ }
+ for (int i = 0; i < initial_files.count(); ++i) {
+ QFile file(test_path + '/' + initial_files.at(i));
+ if (!file.open(QIODevice::WriteOnly | QIODevice::Append)) {
+ qDebug() << "failed to open file" << initial_files.at(i);
+ return false;
+ }
+ if (!file.resize(1024 + file.size())) {
+ qDebug() << "failed to resize file" << initial_files.at(i);
+ return false;
+ }
+ if (!file.flush()) {
+ qDebug() << "failed to flush file" << initial_files.at(i);
+ return false;
+ }
+ file.close();
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ if (initial_files.at(i)[0] == '.')
+ QProcess::execute(QString("attrib +h %1").arg(file.fileName()));
+#endif
+ //qDebug() << test_path + '/' + initial_files.at(i) << (QFile::exists(test_path + '/' + initial_files.at(i)));
+ }
+ return true;
+}
+
+void tst_QFileSystemModel::rowCount()
+{
+ QString tmp = flatDirTestPath;
+ QVERIFY(createFiles(tmp, QStringList()));
+
+ QSignalSpy spy2(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)));
+ QSignalSpy spy3(model, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)));
+
+#if !defined(Q_OS_WINCE)
+ QStringList files = QStringList() << "b" << "d" << "f" << "h" << "j" << ".a" << ".c" << ".e" << ".g";
+ QString l = "b,d,f,h,j,.a,.c,.e,.g";
+#else
+ // Cannot hide them on CE
+ QStringList files = QStringList() << "b" << "d" << "f" << "h" << "j";
+ QString l = "b,d,f,h,j";
+#endif
+ QVERIFY(createFiles(tmp, files));
+
+ QModelIndex root = model->setRootPath(tmp);
+ QTRY_COMPARE(model->rowCount(root), 5);
+ QVERIFY(spy2.count() > 0);
+ QVERIFY(spy3.count() > 0);
+}
+
+void tst_QFileSystemModel::rowsInserted_data()
+{
+ QTest::addColumn<int>("count");
+ QTest::addColumn<int>("assending");
+ for (int i = 0; i < 4; ++i) {
+ QTest::newRow(QString("Qt::AscendingOrder %1").arg(i).toLocal8Bit().constData()) << i << (int)Qt::AscendingOrder;
+ QTest::newRow(QString("Qt::DescendingOrder %1").arg(i).toLocal8Bit().constData()) << i << (int)Qt::DescendingOrder;
+ }
+}
+
+void tst_QFileSystemModel::rowsInserted()
+{
+#if defined(Q_OS_WINCE)
+ QSKIP("Watching directories does not work on CE(see #137910)", SkipAll);
+#endif
+ QString tmp = flatDirTestPath;
+ rowCount();
+ QModelIndex root = model->index(model->rootPath());
+
+ QFETCH(int, assending);
+ QFETCH(int, count);
+ model->sort(0, (Qt::SortOrder)assending);
+
+ QSignalSpy spy0(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)));
+ QSignalSpy spy1(model, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)));
+ int oldCount = model->rowCount(root);
+ QStringList files;
+ for (int i = 0; i < count; ++i)
+ files.append(QString("c%1").arg(i));
+ QVERIFY(createFiles(tmp, files, 5));
+ TRY_WAIT(model->rowCount(root) == oldCount + count);
+ QTRY_COMPARE(model->rowCount(root), oldCount + count);
+ QTest::qWait(100); // Let the sort settle.
+ int totalRowsInserted = 0;
+ for (int i = 0; i < spy0.count(); ++i) {
+ int start = spy0[i].value(1).toInt();
+ int end = spy0[i].value(2).toInt();
+ totalRowsInserted += end - start + 1;
+ }
+ QCOMPARE(totalRowsInserted, count);
+ if (assending == (Qt::SortOrder)Qt::AscendingOrder) {
+ QString letter = model->index(model->rowCount(root) - 1, 0, root).data().toString();
+ QCOMPARE(letter, QString("j"));
+ } else {
+ QCOMPARE(model->index(model->rowCount(root) - 1, 0, root).data().toString(), QString("b"));
+ }
+ if (spy0.count() > 0) {
+ if (count == 0)
+ QCOMPARE(spy0.count(), 0);
+ else
+ QVERIFY(spy0.count() >= 1);
+ }
+ if (count == 0) QCOMPARE(spy1.count(), 0); else QVERIFY(spy1.count() >= 1);
+
+ QVERIFY(createFiles(tmp, QStringList(".hidden_file"), 5 + count));
+
+ if (count != 0) QTRY_VERIFY(spy0.count() >= 1); else QTRY_VERIFY(spy0.count() == 0);
+ if (count != 0) QTRY_VERIFY(spy1.count() >= 1); else QTRY_VERIFY(spy1.count() == 0);
+}
+
+void tst_QFileSystemModel::rowsRemoved_data()
+{
+ rowsInserted_data();
+}
+
+void tst_QFileSystemModel::rowsRemoved()
+{
+#if defined(Q_OS_WINCE)
+ QSKIP("Watching directories does not work on CE(see #137910)", SkipAll);
+#endif
+ QString tmp = flatDirTestPath;
+ rowCount();
+ QModelIndex root = model->index(model->rootPath());
+
+ QFETCH(int, count);
+ QFETCH(int, assending);
+ model->sort(0, (Qt::SortOrder)assending);
+ QTest::qWait(WAITTIME);
+
+ QSignalSpy spy0(model, SIGNAL(rowsRemoved(const QModelIndex &, int, int)));
+ QSignalSpy spy1(model, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)));
+ int oldCount = model->rowCount(root);
+ for (int i = count - 1; i >= 0; --i) {
+ //qDebug() << "removing" << model->index(i, 0, root).data().toString();
+ QVERIFY(QFile::remove(tmp + '/' + model->index(i, 0, root).data().toString()));
+ }
+ for (int i = 0 ; i < 10; ++i) {
+ QTest::qWait(WAITTIME);
+ qApp->processEvents();
+ if (count != 0) {
+ if (i == 10 || spy0.count() != 0) {
+ QVERIFY(spy0.count() >= 1);
+ QVERIFY(spy1.count() >= 1);
+ }
+ } else {
+ if (i == 10 || spy0.count() == 0) {
+ QVERIFY(spy0.count() == 0);
+ QVERIFY(spy1.count() == 0);
+ }
+ }
+ QStringList lst;
+ for (int i = 0; i < model->rowCount(root); ++i)
+ lst.append(model->index(i, 0, root).data().toString());
+ if (model->rowCount(root) == oldCount - count)
+ break;
+ qDebug() << "still have:" << lst << QFile::exists(tmp + '/' + QString(".a"));
+ QDir tmpLister(tmp);
+ qDebug() << tmpLister.entryList();
+ }
+ QTRY_COMPARE(model->rowCount(root), oldCount - count);
+
+ QVERIFY(QFile::exists(tmp + '/' + QString(".a")));
+ QVERIFY(QFile::remove(tmp + '/' + QString(".a")));
+ QVERIFY(QFile::remove(tmp + '/' + QString(".c")));
+ QTest::qWait(WAITTIME);
+
+ if (count != 0) QVERIFY(spy0.count() >= 1); else QVERIFY(spy0.count() == 0);
+ if (count != 0) QVERIFY(spy1.count() >= 1); else QVERIFY(spy1.count() == 0);
+}
+
+void tst_QFileSystemModel::dataChanged_data()
+{
+ rowsInserted_data();
+}
+
+void tst_QFileSystemModel::dataChanged()
+{
+ // This can't be tested right now sense we don't watch files, only directories
+ return;
+
+ /*
+ QString tmp = flatDirTestPath;
+ rowCount();
+ QModelIndex root = model->index(model->rootPath());
+
+ QFETCH(int, count);
+ QFETCH(int, assending);
+ model->sort(0, (Qt::SortOrder)assending);
+
+ QSignalSpy spy(model, SIGNAL(dataChanged (const QModelIndex &, const QModelIndex &)));
+ QStringList files;
+ for (int i = 0; i < count; ++i)
+ files.append(model->index(i, 0, root).data().toString());
+ createFiles(tmp, files);
+
+ QTest::qWait(WAITTIME);
+
+ if (count != 0) QVERIFY(spy.count() >= 1); else QVERIFY(spy.count() == 0);
+ */
+}
+
+void tst_QFileSystemModel::filters_data()
+{
+ QTest::addColumn<QStringList>("files");
+ QTest::addColumn<QStringList>("dirs");
+ QTest::addColumn<int>("dirFilters");
+ QTest::addColumn<QStringList>("nameFilters");
+ QTest::addColumn<int>("rowCount");
+#if !defined(Q_OS_WINCE)
+ QTest::newRow("no dirs") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs) << QStringList() << 2;
+ QTest::newRow("no dirs - dot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDot) << QStringList() << 1;
+ QTest::newRow("no dirs - dotdot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDotDot) << QStringList() << 1;
+ QTest::newRow("no dirs - dotanddotdot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 0;
+ QTest::newRow("one dir - dot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDot) << QStringList() << 2;
+ QTest::newRow("one dir - dotdot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDotDot) << QStringList() << 2;
+ QTest::newRow("one dir - dotanddotdot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 1;
+ QTest::newRow("one dir") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs) << QStringList() << 3;
+ QTest::newRow("no dir + hidden") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::Hidden) << QStringList() << 2;
+ QTest::newRow("dir+hid+files") << (QStringList() << "a" << "b" << "c") << QStringList() <<
+ (int)(QDir::Dirs | QDir::Files | QDir::Hidden) << QStringList() << 5;
+ QTest::newRow("dir+file+hid-dot .A") << (QStringList() << "a" << "b" << "c") << (QStringList() << ".A") <<
+ (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot) << QStringList() << 4;
+ QTest::newRow("dir+files+hid+dot A") << (QStringList() << "a" << "b" << "c") << (QStringList() << "AFolder") <<
+ (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot) << (QStringList() << "A*") << 2;
+ QTest::newRow("dir+files+hid+dot+cas1") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") <<
+ (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::CaseSensitive) << (QStringList() << "Z") << 1;
+ QTest::newRow("dir+files+hid+dot+cas2") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") <<
+ (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::CaseSensitive) << (QStringList() << "a") << 1;
+ QTest::newRow("dir+files+hid+dot+cas+alldir") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") <<
+ (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::CaseSensitive | QDir::AllDirs) << (QStringList() << "Z") << 1;
+#else
+ QTest::qWait(3000); // We need to calm down a bit...
+ QTest::newRow("no dirs") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs) << QStringList() << 0;
+ QTest::newRow("no dirs - dot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDot) << QStringList() << 1;
+ QTest::newRow("no dirs - dotdot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDotDot) << QStringList() << 1;
+ QTest::newRow("no dirs - dotanddotdot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 0;
+ QTest::newRow("one dir - dot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDot) << QStringList() << 2;
+ QTest::newRow("one dir - dotdot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDotDot) << QStringList() << 2;
+ QTest::newRow("one dir - dotanddotdot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 1;
+ QTest::newRow("one dir") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs) << QStringList() << 1;
+ QTest::newRow("no dir + hidden") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::Hidden) << QStringList() << 0;
+ QTest::newRow("dir+hid+files") << (QStringList() << "a" << "b" << "c") << QStringList() <<
+ (int)(QDir::Dirs | QDir::Files | QDir::Hidden) << QStringList() << 3;
+ QTest::newRow("dir+file+hid-dot .A") << (QStringList() << "a" << "b" << "c") << (QStringList() << ".A") <<
+ (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot) << QStringList() << 4;
+ QTest::newRow("dir+files+hid+dot A") << (QStringList() << "a" << "b" << "c") << (QStringList() << "AFolder") <<
+ (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot) << (QStringList() << "A*") << 2;
+ QTest::newRow("dir+files+hid+dot+cas1") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") <<
+ (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::CaseSensitive) << (QStringList() << "Z") << 1;
+ QTest::newRow("dir+files+hid+dot+cas2") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") <<
+ (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::CaseSensitive) << (QStringList() << "a") << 1;
+ QTest::newRow("dir+files+hid+dot+cas+alldir") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") <<
+ (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::CaseSensitive | QDir::AllDirs) << (QStringList() << "Z") << 1;
+#endif
+
+ QTest::newRow("case sensitive") << (QStringList() << "Antiguagdb" << "Antiguamtd"
+ << "Antiguamtp" << "afghanistangdb" << "afghanistanmtd")
+ << QStringList() << (int)(QDir::Files) << QStringList() << 5;
+}
+
+void tst_QFileSystemModel::filters()
+{
+ QString tmp = flatDirTestPath;
+ QVERIFY(createFiles(tmp, QStringList()));
+ QModelIndex root = model->setRootPath(tmp);
+ QFETCH(QStringList, files);
+ QFETCH(QStringList, dirs);
+ QFETCH(int, dirFilters);
+ QFETCH(QStringList, nameFilters);
+ QFETCH(int, rowCount);
+
+ if (nameFilters.count() > 0)
+ model->setNameFilters(nameFilters);
+ model->setNameFilterDisables(false);
+ model->setFilter((QDir::Filters)dirFilters);
+
+ QVERIFY(createFiles(tmp, files, 0, dirs));
+ QTRY_COMPARE(model->rowCount(root), rowCount);
+
+ // Make sure that we do what QDir does
+ QDir xFactor(tmp);
+ QDir::Filters filters = (QDir::Filters)dirFilters;
+ QStringList dirEntries;
+
+ if (nameFilters.count() > 0)
+ dirEntries = xFactor.entryList(nameFilters, filters);
+ else
+ dirEntries = xFactor.entryList(filters);
+
+ QCOMPARE(dirEntries.count(), rowCount);
+
+ QStringList modelEntries;
+
+ for (int i = 0; i < rowCount; ++i)
+ modelEntries.append(model->data(model->index(i, 0, root), QFileSystemModel::FileNameRole).toString());
+
+ qSort(dirEntries);
+ qSort(modelEntries);
+ QCOMPARE(dirEntries, modelEntries);
+
+#ifdef Q_OS_LINUX
+ if (files.count() >= 3 && rowCount >= 3 && rowCount != 5) {
+ QString fileName1 = (tmp + '/' + files.at(0));
+ QString fileName2 = (tmp + '/' + files.at(1));
+ QString fileName3 = (tmp + '/' + files.at(2));
+ QFile::Permissions originalPermissions = QFile::permissions(fileName1);
+ QVERIFY(QFile::setPermissions(fileName1, QFile::WriteOwner));
+ QVERIFY(QFile::setPermissions(fileName2, QFile::ReadOwner));
+ QVERIFY(QFile::setPermissions(fileName3, QFile::ExeOwner));
+
+ model->setFilter((QDir::Files | QDir::Readable));
+ QTRY_COMPARE(model->rowCount(root), 1);
+
+ model->setFilter((QDir::Files | QDir::Writable));
+ QTRY_COMPARE(model->rowCount(root), 1);
+
+ model->setFilter((QDir::Files | QDir::Executable));
+ QTRY_COMPARE(model->rowCount(root), 1);
+
+ // reset permissions
+ QVERIFY(QFile::setPermissions(fileName1, originalPermissions));
+ QVERIFY(QFile::setPermissions(fileName2, originalPermissions));
+ QVERIFY(QFile::setPermissions(fileName3, originalPermissions));
+ }
+#endif
+}
+
+void tst_QFileSystemModel::nameFilters()
+{
+ QStringList list;
+ list << "a" << "b" << "c";
+ model->setNameFilters(list);
+ model->setNameFilterDisables(false);
+ QCOMPARE(model->nameFilters(), list);
+
+ QString tmp = flatDirTestPath;
+ QVERIFY(createFiles(tmp, list));
+ QModelIndex root = model->setRootPath(tmp);
+ QTRY_COMPARE(model->rowCount(root), 3);
+
+ QStringList filters;
+ filters << "a" << "b";
+ model->setNameFilters(filters);
+ QTRY_COMPARE(model->rowCount(root), 2);
+}
+void tst_QFileSystemModel::setData_data()
+{
+ QTest::addColumn<QStringList>("files");
+ QTest::addColumn<QString>("oldFileName");
+ QTest::addColumn<QString>("newFileName");
+ QTest::addColumn<bool>("success");
+ /*QTest::newRow("outside current dir") << (QStringList() << "a" << "b" << "c")
+ << flatDirTestPath + '/' + "a"
+ << QDir::temp().absolutePath() + '/' + "a"
+ << false;
+ */
+ QTest::newRow("in current dir") << (QStringList() << "a" << "b" << "c")
+ << "a"
+ << "d"
+ << true;
+}
+
+void tst_QFileSystemModel::setData()
+{
+ QSignalSpy spy(model, SIGNAL(fileRenamed(const QString&, const QString&, const QString&)));
+ QString tmp = flatDirTestPath;
+ QFETCH(QStringList, files);
+ QFETCH(QString, oldFileName);
+ QFETCH(QString, newFileName);
+ QFETCH(bool, success);
+
+ QVERIFY(createFiles(tmp, files));
+ QModelIndex root = model->setRootPath(tmp);
+ QTRY_COMPARE(model->rowCount(root), files.count());
+
+ QModelIndex idx = model->index(tmp + '/' + oldFileName);
+ QCOMPARE(idx.isValid(), true);
+ QCOMPARE(model->setData(idx, newFileName), false);
+
+ model->setReadOnly(false);
+ QCOMPARE(model->setData(idx, newFileName), success);
+ if (success) {
+ QCOMPARE(spy.count(), 1);
+ QList<QVariant> arguments = spy.takeFirst();
+ QCOMPARE(model->data(idx, QFileSystemModel::FileNameRole).toString(), newFileName);
+ QCOMPARE(model->index(arguments.at(0).toString()), model->index(tmp));
+ QCOMPARE(arguments.at(1).toString(), oldFileName);
+ QCOMPARE(arguments.at(2).toString(), newFileName);
+ QCOMPARE(QFile::rename(tmp + '/' + newFileName, tmp + '/' + oldFileName), true);
+ }
+ QTRY_COMPARE(model->rowCount(root), files.count());
+}
+
+class MyFriendFileSystemModel : public QFileSystemModel
+{
+ friend class tst_QFileSystemModel;
+ Q_DECLARE_PRIVATE(QFileSystemModel)
+};
+
+void tst_QFileSystemModel::sort_data()
+{
+ QTest::addColumn<bool>("fileDialogMode");
+ QTest::newRow("standard usage") << false;
+ QTest::newRow("QFileDialog usage") << true;
+}
+
+void tst_QFileSystemModel::sort()
+{
+ QTemporaryFile file;
+ file.open();
+ QModelIndex root = model->setRootPath(QDir::tempPath());
+ QTRY_VERIFY(model->rowCount(root) > 0);
+
+ QPersistentModelIndex idx = model->index(0, 1, root);
+ model->sort(0, Qt::AscendingOrder);
+ model->sort(0, Qt::DescendingOrder);
+ QVERIFY(idx.column() != 0);
+
+ model->setRootPath(QDir::homePath());
+
+ QFETCH(bool, fileDialogMode);
+
+ MyFriendFileSystemModel *myModel = new MyFriendFileSystemModel();
+ QTreeView *tree = new QTreeView();
+
+#ifdef QT_BUILD_INTERNAL
+ if (fileDialogMode)
+ myModel->d_func()->disableRecursiveSort = true;
+#endif
+
+ QDir dir(QDir::tempPath());
+ //initialize the randomness
+ qsrand(QDateTime::currentDateTime().toTime_t());
+ QString tempName = QLatin1String("sortTemp.") + QString::number(qrand());
+ dir.mkdir(tempName);
+ dir.cd(tempName);
+ QTRY_VERIFY(dir.exists());
+
+ const QString dirPath = dir.absolutePath();
+ QVERIFY(dir.exists());
+
+ //Create a file that will be at the end when sorting by name (For Mac, the default)
+ //but if we sort by size descending it will be the first
+ QFile tempFile(dirPath + "/plop2.txt");
+ tempFile.open(QIODevice::WriteOnly | QIODevice::Text);
+ QTextStream out(&tempFile);
+ out << "The magic number is: " << 49 << "\n";
+ tempFile.close();
+
+ QFile tempFile2(dirPath + "/plop.txt");
+ tempFile2.open(QIODevice::WriteOnly | QIODevice::Text);
+ QTextStream out2(&tempFile2);
+ out2 << "The magic number is : " << 49 << " but i write some stuff in the file \n";
+ tempFile2.close();
+
+ myModel->setRootPath("");
+ myModel->setFilter(QDir::AllEntries | QDir::System | QDir::Hidden);
+ tree->setSortingEnabled(true);
+ tree->setModel(myModel);
+ tree->show();
+ tree->resize(800, 800);
+ QTest::qWait(500);
+ tree->header()->setSortIndicator(1,Qt::DescendingOrder);
+ tree->header()->setResizeMode(0, QHeaderView::ResizeToContents);
+ QStringList dirsToOpen;
+ do
+ {
+ dirsToOpen<<dir.absolutePath();
+ } while (dir.cdUp());
+
+ for (int i = dirsToOpen.size() -1 ; i > 0 ; --i) {
+ QString path = dirsToOpen[i];
+ QTest::qWait(500);
+ tree->expand(myModel->index(path, 0));
+ }
+ tree->expand(myModel->index(dirPath, 0));
+ QTest::qWait(500);
+ QModelIndex parent = myModel->index(dirPath, 0);
+ QList<QString> expectedOrder;
+ expectedOrder << tempFile2.fileName() << tempFile.fileName() << dirPath + QChar('/') + "." << dirPath + QChar('/') + "..";
+ //File dialog Mode means sub trees are not sorted, only the current root
+ if (fileDialogMode) {
+ // FIXME: we were only able to disableRecursiveSort in developer builds, so we can only
+ // stably perform this test for developer builds
+#ifdef QT_BUILD_INTERNAL
+ QList<QString> actualRows;
+ for(int i = 0; i < myModel->rowCount(parent); ++i)
+ {
+ actualRows << dirPath + QChar('/') + myModel->index(i, 1, parent).data(QFileSystemModel::FileNameRole).toString();
+ }
+ QVERIFY(actualRows != expectedOrder);
+#endif
+ } else {
+ for(int i = 0; i < myModel->rowCount(parent); ++i)
+ {
+ QTRY_COMPARE(dirPath + QChar('/') + myModel->index(i, 1, parent).data(QFileSystemModel::FileNameRole).toString(), expectedOrder.at(i));
+ }
+ }
+
+ delete tree;
+ delete myModel;
+
+ dir.setPath(QDir::tempPath());
+ dir.cd(tempName);
+ tempFile.remove();
+ tempFile2.remove();
+ dir.cdUp();
+ dir.rmdir(tempName);
+
+}
+
+void tst_QFileSystemModel::mkdir()
+{
+ QString tmp = QDir::tempPath();
+ QString newFolderPath = QDir::toNativeSeparators(tmp + '/' + "NewFoldermkdirtest4");
+ QModelIndex tmpDir = model->index(tmp);
+ QVERIFY(tmpDir.isValid());
+ QDir bestatic(newFolderPath);
+ if (bestatic.exists()) {
+ if (!bestatic.rmdir(newFolderPath))
+ qWarning() << "unable to remove" << newFolderPath;
+ QTest::qWait(WAITTIME);
+ }
+ model->mkdir(tmpDir, "NewFoldermkdirtest3");
+ model->mkdir(tmpDir, "NewFoldermkdirtest5");
+ QModelIndex idx = model->mkdir(tmpDir, "NewFoldermkdirtest4");
+ QVERIFY(idx.isValid());
+ int oldRow = idx.row();
+ QTest::qWait(WAITTIME);
+ idx = model->index(newFolderPath);
+ QDir cleanup(tmp);
+ QVERIFY(cleanup.rmdir(QLatin1String("NewFoldermkdirtest3")));
+ QVERIFY(cleanup.rmdir(QLatin1String("NewFoldermkdirtest5")));
+ bestatic.rmdir(newFolderPath);
+ QVERIFY(0 != idx.row());
+ QCOMPARE(oldRow, idx.row());
+}
+
+void tst_QFileSystemModel::caseSensitivity()
+{
+ QString tmp = flatDirTestPath;
+ QStringList files;
+ files << "a" << "c" << "C";
+ QVERIFY(createFiles(tmp, files));
+ QModelIndex root = model->index(tmp);
+ QCOMPARE(model->rowCount(root), 0);
+ for (int i = 0; i < files.count(); ++i) {
+ QVERIFY(model->index(tmp + '/' + files.at(i)).isValid());
+ }
+}
+
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+void tst_QFileSystemModel::Win32LongFileName()
+{
+ QString tmp = flatDirTestPath;
+ QStringList files;
+ files << "aaaaaaaaaa" << "bbbbbbbbbb" << "cccccccccc";
+ QVERIFY(createFiles(tmp, files));
+ QModelIndex root = model->setRootPath(tmp);
+ QTRY_VERIFY(model->index(tmp + QLatin1String("/aaaaaa~1")).isValid());
+ QTRY_VERIFY(model->index(tmp + QLatin1String("/bbbbbb~1")).isValid());
+ QTRY_VERIFY(model->index(tmp + QLatin1String("/cccccc~1")).isValid());
+}
+#endif
+
+void tst_QFileSystemModel::drives_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::newRow("current") << QDir::currentPath();
+ QTest::newRow("slash") << "/";
+ QTest::newRow("My Computer") << "My Computer";
+}
+
+void tst_QFileSystemModel::drives()
+{
+ QFETCH(QString, path);
+ QFileSystemModel model;
+ model.setRootPath(path);
+ model.fetchMore(QModelIndex());
+ QFileInfoList drives = QDir::drives();
+ int driveCount = 0;
+ foreach(const QFileInfo& driveRoot, drives)
+ if (driveRoot.exists())
+ driveCount++;
+ QTest::qWait(5000);
+ QTRY_COMPARE(model.rowCount(), driveCount);
+}
+
+void tst_QFileSystemModel::dirsBeforeFiles()
+{
+ const QString dirPath = QString("%1/task221717_sortedOrder_test_dir").arg(QDir::tempPath());
+ QDir dir(dirPath);
+ // clean up from last time
+ if (dir.exists()) {
+ for (int i = 0; i < 3; ++i) {
+ QLatin1Char c('a' + i);
+ dir.rmdir(QString("%1-dir").arg(c));
+ QFile::remove(dirPath + QString("/%1-file").arg(c));
+ }
+ dir.rmdir(dirPath);
+ }
+ QVERIFY(dir.mkpath(dirPath));
+ QVERIFY(QDir(dirPath).exists());
+
+ for (int i = 0; i < 3; ++i) {
+ QLatin1Char c('a' + i);
+ dir.mkdir(QString("%1-dir").arg(c));
+ QFile file(dirPath + QString("/%1-file").arg(c));
+ file.open(QIODevice::ReadWrite);
+ file.close();
+ }
+
+ QModelIndex root = model->setRootPath(dirPath);
+ QTest::qWait(1000); // allow model to be notified by the file system watcher
+
+ // ensure that no file occurs before a directory
+ for (int i = 0; i < model->rowCount(root); ++i) {
+#ifndef Q_OS_MAC
+ QVERIFY(i == 0 ||
+ !(model->fileInfo(model->index(i - 1, 0, root)).isFile()
+ && model->fileInfo(model->index(i, 0, root)).isDir()));
+#else
+ QVERIFY(i == 0 ||
+ model->fileInfo(model->index(i - 1, 0, root)).fileName() <
+ model->fileInfo(model->index(i, 0, root)).fileName());
+#endif
+ }
+}
+
+void tst_QFileSystemModel::roleNames_data()
+{
+ QTest::addColumn<int>("role");
+ QTest::addColumn<QByteArray>("roleName");
+ QTest::newRow("decoration") << int(Qt::DecorationRole) << QByteArray("decoration");
+ QTest::newRow("display") << int(Qt::DisplayRole) << QByteArray("display");
+ QTest::newRow("fileIcon") << int(QFileSystemModel::FileIconRole) << QByteArray("fileIcon");
+ QTest::newRow("filePath") << int(QFileSystemModel::FilePathRole) << QByteArray("filePath");
+ QTest::newRow("fileName") << int(QFileSystemModel::FileNameRole) << QByteArray("fileName");
+ QTest::newRow("filePermissions") << int(QFileSystemModel::FilePermissions) << QByteArray("filePermissions");
+}
+
+void tst_QFileSystemModel::roleNames()
+{
+ QFileSystemModel model;
+ QHash<int, QByteArray> roles = model.roleNames();
+
+ QFETCH(int, role);
+ QVERIFY(roles.contains(role));
+
+ QFETCH(QByteArray, roleName);
+ QList<QByteArray> values = roles.values(role);
+ QVERIFY(values.contains(roleName));
+}
+
+QTEST_MAIN(tst_QFileSystemModel)
+#include "tst_qfilesystemmodel.moc"
+
diff --git a/tests/auto/widgets/dialogs/qfontdialog/.gitignore b/tests/auto/widgets/dialogs/qfontdialog/.gitignore
new file mode 100644
index 0000000000..5bd48d4951
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfontdialog/.gitignore
@@ -0,0 +1 @@
+tst_qfontdialog
diff --git a/tests/auto/widgets/dialogs/qfontdialog/qfontdialog.pro b/tests/auto/widgets/dialogs/qfontdialog/qfontdialog.pro
new file mode 100644
index 0000000000..5a0c2b66bf
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfontdialog/qfontdialog.pro
@@ -0,0 +1,12 @@
+load(qttest_p4)
+
+QT += widgets widgets-private
+QT += core-private gui-private
+
+SOURCES += tst_qfontdialog.cpp
+
+mac:!qpa {
+ OBJECTIVE_SOURCES += tst_qfontdialog_mac_helpers.mm
+ LIBS += -framework Cocoa
+}
+
diff --git a/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp b/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp
new file mode 100644
index 0000000000..3f12b7501c
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+
+#include <qapplication.h>
+#include <qfontinfo.h>
+#include <qtimer.h>
+#include <qmainwindow.h>
+#include <qlistview.h>
+#include "qfontdialog.h"
+#include <private/qfontdialog_p.h>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+QT_FORWARD_DECLARE_CLASS(QtTestEventThread)
+
+class tst_QFontDialog : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QFontDialog();
+ virtual ~tst_QFontDialog();
+
+
+public slots:
+ void postKeyReturn();
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+ void init();
+ void cleanup();
+private slots:
+ void defaultOkButton();
+ void setFont();
+ void task256466_wrongStyle();
+};
+
+tst_QFontDialog::tst_QFontDialog()
+{
+}
+
+tst_QFontDialog::~tst_QFontDialog()
+{
+}
+
+void tst_QFontDialog::initTestCase()
+{
+}
+
+void tst_QFontDialog::cleanupTestCase()
+{
+}
+
+void tst_QFontDialog::init()
+{
+}
+
+void tst_QFontDialog::cleanup()
+{
+}
+
+
+void tst_QFontDialog::postKeyReturn() {
+#ifndef Q_WS_MAC
+ QWidgetList list = QApplication::topLevelWidgets();
+ for (int i=0; i<list.count(); ++i) {
+ QFontDialog *dialog = qobject_cast<QFontDialog*>(list[i]);
+ if (dialog) {
+ QTest::keyClick( list[i], Qt::Key_Return, Qt::NoModifier );
+ return;
+ }
+ }
+#else
+ extern void click_cocoa_button();
+ click_cocoa_button();
+#endif
+}
+
+void tst_QFontDialog::defaultOkButton()
+{
+ bool ok = FALSE;
+ QTimer::singleShot(2000, this, SLOT(postKeyReturn()));
+ QFontDialog::getFont(&ok);
+ QVERIFY(ok == TRUE);
+}
+
+
+void tst_QFontDialog::setFont()
+{
+ /* The font should be the same before as it is after if nothing changed
+ while the font dialog was open.
+ Task #27662
+ */
+ bool ok = FALSE;
+#if defined Q_OS_HPUX
+ QString fontName = "Courier";
+ int fontSize = 25;
+#elif defined Q_OS_AIX
+ QString fontName = "Charter";
+ int fontSize = 13;
+#else
+ QString fontName = "Arial";
+ int fontSize = 24;
+#endif
+ QFont f1(fontName, fontSize);
+ f1.setPixelSize(QFontInfo(f1).pixelSize());
+ QTimer::singleShot(2000, this, SLOT(postKeyReturn()));
+ QFont f2 = QFontDialog::getFont(&ok, f1);
+ QCOMPARE(QFontInfo(f2).pointSize(), QFontInfo(f1).pointSize());
+}
+
+
+class FriendlyFontDialog : public QFontDialog
+{
+ friend class tst_QFontDialog;
+ Q_DECLARE_PRIVATE(QFontDialog);
+};
+
+void tst_QFontDialog::task256466_wrongStyle()
+{
+ QFontDatabase fdb;
+ FriendlyFontDialog dialog;
+ QListView *familyList = reinterpret_cast<QListView*>(dialog.d_func()->familyList);
+ QListView *styleList = reinterpret_cast<QListView*>(dialog.d_func()->styleList);
+ QListView *sizeList = reinterpret_cast<QListView*>(dialog.d_func()->sizeList);
+ for (int i = 0; i < familyList->model()->rowCount(); ++i) {
+ QModelIndex currentFamily = familyList->model()->index(i, 0);
+ familyList->setCurrentIndex(currentFamily);
+ const QFont current = dialog.currentFont(),
+ expected = fdb.font(currentFamily.data().toString(),
+ styleList->currentIndex().data().toString(), sizeList->currentIndex().data().toInt());
+ QCOMPARE(current.family(), expected.family());
+ QCOMPARE(current.style(), expected.style());
+ QCOMPARE(current.pointSizeF(), expected.pointSizeF());
+ }
+}
+
+
+
+
+QTEST_MAIN(tst_QFontDialog)
+#include "tst_qfontdialog.moc"
diff --git a/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog_mac_helpers.mm b/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog_mac_helpers.mm
new file mode 100644
index 0000000000..d12f696f7e
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog_mac_helpers.mm
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <private/qt_mac_p.h>
+#include <AppKit/AppKit.h>
+
+void click_cocoa_button()
+{
+ QMacCocoaAutoReleasePool pool;
+ NSArray *windows = [NSApp windows];
+ for (NSWindow *window in windows) {
+ // This is NOT how one should do RTTI, but since I don't want to leak the class too much...
+ if ([[window delegate] respondsToSelector:@selector(qtFont)]) {
+ NSArray *subviews = [[window contentView] subviews];
+ for (NSView *view in subviews) {
+ if ([view isKindOfClass:[NSButton class]]
+ && [[static_cast<NSButton *>(view) title] isEqualTo:@"OK"]) {
+ [static_cast<NSButton *>(view) performClick:view];
+ [NSApp postEvent:[NSEvent otherEventWithType:NSApplicationDefined location:NSZeroPoint
+ modifierFlags:0 timestamp:0. windowNumber:0 context:0
+ subtype:SHRT_MAX data1:0 data2:0] atStart:NO];
+
+ break;
+ }
+ }
+ break;
+ }
+ }
+}
diff --git a/tests/auto/widgets/dialogs/qinputdialog/.gitignore b/tests/auto/widgets/dialogs/qinputdialog/.gitignore
new file mode 100644
index 0000000000..b62797193c
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qinputdialog/.gitignore
@@ -0,0 +1 @@
+tst_qinputdialog
diff --git a/tests/auto/widgets/dialogs/qinputdialog/qinputdialog.pro b/tests/auto/widgets/dialogs/qinputdialog/qinputdialog.pro
new file mode 100644
index 0000000000..f7e56bd783
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qinputdialog/qinputdialog.pro
@@ -0,0 +1,5 @@
+load(qttest_p4)
+QT += widgets
+SOURCES += tst_qinputdialog.cpp
+
+
diff --git a/tests/auto/widgets/dialogs/qinputdialog/tst_qinputdialog.cpp b/tests/auto/widgets/dialogs/qinputdialog/tst_qinputdialog.cpp
new file mode 100644
index 0000000000..5c74ab217b
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qinputdialog/tst_qinputdialog.cpp
@@ -0,0 +1,430 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include <QString>
+#include <QSpinBox>
+#include <QPushButton>
+#include <QLineEdit>
+#include <QComboBox>
+#include <QDialogButtonBox>
+#include <qinputdialog.h>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QInputDialog : public QObject
+{
+ Q_OBJECT
+ QWidget *parent;
+ QDialog::DialogCode doneCode;
+ void (*testFunc)(QInputDialog *);
+ static void testFuncGetInteger(QInputDialog *dialog);
+ static void testFuncGetDouble(QInputDialog *dialog);
+ static void testFuncGetText(QInputDialog *dialog);
+ static void testFuncGetItem(QInputDialog *dialog);
+ void timerEvent(QTimerEvent *event);
+private slots:
+ void getInteger_data();
+ void getInteger();
+ void getDouble_data();
+ void getDouble();
+ void task255502getDouble();
+ void getText_data();
+ void getText();
+ void getItem_data();
+ void getItem();
+ void task256299_getTextReturnNullStringOnRejected();
+ void inputMethodHintsOfChildWidget();
+};
+
+QString stripFraction(const QString &s)
+{
+ int period;
+ if (s.contains('.'))
+ period = s.indexOf('.');
+ else if (s.contains(','))
+ period = s.indexOf(',');
+ else
+ return s;
+ int end;
+ for (end = s.size() - 1; end > period && s[end] == '0'; --end) ;
+ return s.left(end + (end == period ? 0 : 1));
+}
+
+QString normalizeNumericString(const QString &s)
+{
+ return stripFraction(s); // assumed to be sufficient
+}
+
+void _keyClick(QWidget *widget, char key)
+{
+ QTest::keyClick(widget, key);
+}
+
+void _keyClick(QWidget *widget, Qt::Key key)
+{
+ QTest::keyClick(widget, key);
+}
+
+template <typename SpinBoxType>
+void testTypingValue(
+ SpinBoxType* sbox, QPushButton *okButton, const QString &value)
+{
+ sbox->selectAll();
+ for (int i = 0; i < value.size(); ++i) {
+ const QChar valChar = value[i];
+ _keyClick(static_cast<QWidget *>(sbox), valChar.toAscii()); // ### always guaranteed to work?
+ if (sbox->hasAcceptableInput())
+ QVERIFY(okButton->isEnabled());
+ else
+ QVERIFY(!okButton->isEnabled());
+ }
+}
+
+void testTypingValue(QLineEdit *ledit, QPushButton *okButton, const QString &value)
+{
+ ledit->selectAll();
+ for (int i = 0; i < value.size(); ++i) {
+ const QChar valChar = value[i];
+ _keyClick(ledit, valChar.toAscii()); // ### always guaranteed to work?
+ QVERIFY(ledit->hasAcceptableInput());
+ QVERIFY(okButton->isEnabled());
+ }
+}
+
+template <typename SpinBoxType, typename ValueType>
+void testInvalidateAndRestore(
+ SpinBoxType* sbox, QPushButton *okButton, QLineEdit *ledit, ValueType * = 0)
+{
+ const ValueType lastValidValue = sbox->value();
+
+ sbox->selectAll();
+ _keyClick(ledit, Qt::Key_Delete);
+ QVERIFY(!sbox->hasAcceptableInput());
+ QVERIFY(!okButton->isEnabled());
+
+ _keyClick(ledit, Qt::Key_Return); // should work with Qt::Key_Enter too
+ QVERIFY(sbox->hasAcceptableInput());
+ QVERIFY(okButton->isEnabled());
+ QCOMPARE(sbox->value(), lastValidValue);
+ QLocale loc;
+ QCOMPARE(
+ normalizeNumericString(ledit->text()),
+ normalizeNumericString(loc.toString(sbox->value())));
+}
+
+template <typename SpinBoxType, typename ValueType>
+void testGetNumeric(QInputDialog *dialog, SpinBoxType * = 0, ValueType * = 0)
+{
+ SpinBoxType *sbox = qFindChild<SpinBoxType *>(dialog);
+ QVERIFY(sbox != 0);
+
+ QLineEdit *ledit = qFindChild<QLineEdit *>(static_cast<QObject *>(sbox));
+ QVERIFY(ledit != 0);
+
+ QDialogButtonBox *bbox = qFindChild<QDialogButtonBox *>(dialog);
+ QVERIFY(bbox != 0);
+ QPushButton *okButton = bbox->button(QDialogButtonBox::Ok);
+ QVERIFY(okButton != 0);
+
+ QVERIFY(sbox->value() >= sbox->minimum());
+ QVERIFY(sbox->value() <= sbox->maximum());
+ QVERIFY(sbox->hasAcceptableInput());
+ QLocale loc;
+ QCOMPARE(
+ normalizeNumericString(ledit->selectedText()),
+ normalizeNumericString(loc.toString(sbox->value())));
+ QVERIFY(okButton->isEnabled());
+
+ const ValueType origValue = sbox->value();
+
+ testInvalidateAndRestore<SpinBoxType, ValueType>(sbox, okButton, ledit);
+ testTypingValue<SpinBoxType>(sbox, okButton, QString("%1").arg(sbox->minimum()));
+ testTypingValue<SpinBoxType>(sbox, okButton, QString("%1").arg(sbox->maximum()));
+ testTypingValue<SpinBoxType>(sbox, okButton, QString("%1").arg(sbox->minimum() - 1));
+ testTypingValue<SpinBoxType>(sbox, okButton, QString("%1").arg(sbox->maximum() + 1));
+ testTypingValue<SpinBoxType>(sbox, okButton, "0");
+ testTypingValue<SpinBoxType>(sbox, okButton, "0.0");
+ testTypingValue<SpinBoxType>(sbox, okButton, "foobar");
+
+ testTypingValue<SpinBoxType>(sbox, okButton, loc.toString(origValue));
+}
+
+void testGetText(QInputDialog *dialog)
+{
+ QLineEdit *ledit = qFindChild<QLineEdit *>(dialog);
+ QVERIFY(ledit);
+
+ QDialogButtonBox *bbox = qFindChild<QDialogButtonBox *>(dialog);
+ QVERIFY(bbox);
+ QPushButton *okButton = bbox->button(QDialogButtonBox::Ok);
+ QVERIFY(okButton);
+
+ QVERIFY(ledit->hasAcceptableInput());
+ QCOMPARE(ledit->selectedText(), ledit->text());
+ QVERIFY(okButton->isEnabled());
+ const QString origValue = ledit->text();
+
+ testTypingValue(ledit, okButton, origValue);
+}
+
+void testGetItem(QInputDialog *dialog)
+{
+ QComboBox *cbox = qFindChild<QComboBox *>(dialog);
+ QVERIFY(cbox);
+
+ QDialogButtonBox *bbox = qFindChild<QDialogButtonBox *>(dialog);
+ QVERIFY(bbox);
+ QPushButton *okButton = bbox->button(QDialogButtonBox::Ok);
+ QVERIFY(okButton);
+
+ QVERIFY(okButton->isEnabled());
+ const int origIndex = cbox->currentIndex();
+ cbox->setCurrentIndex(origIndex - 1);
+ cbox->setCurrentIndex(origIndex);
+ QVERIFY(okButton->isEnabled());
+}
+
+void tst_QInputDialog::testFuncGetInteger(QInputDialog *dialog)
+{
+ testGetNumeric<QSpinBox, int>(dialog);
+}
+
+void tst_QInputDialog::testFuncGetDouble(QInputDialog *dialog)
+{
+ testGetNumeric<QDoubleSpinBox, double>(dialog);
+}
+
+void tst_QInputDialog::testFuncGetText(QInputDialog *dialog)
+{
+ ::testGetText(dialog);
+}
+
+void tst_QInputDialog::testFuncGetItem(QInputDialog *dialog)
+{
+ ::testGetItem(dialog);
+}
+
+void tst_QInputDialog::timerEvent(QTimerEvent *event)
+{
+ killTimer(event->timerId());
+ QInputDialog *dialog = qFindChild<QInputDialog *>(parent);
+ QVERIFY(dialog);
+ if (testFunc)
+ testFunc(dialog);
+ dialog->done(doneCode); // cause static function call to return
+}
+
+void tst_QInputDialog::getInteger_data()
+{
+ QTest::addColumn<int>("min");
+ QTest::addColumn<int>("max");
+ QTest::newRow("getInteger() - -") << -20 << -10;
+ QTest::newRow("getInteger() - 0") << -20 << 0;
+ QTest::newRow("getInteger() - +") << -20 << 20;
+ QTest::newRow("getInteger() 0 +") << 0 << 20;
+ QTest::newRow("getInteger() + +") << 10 << 20;
+}
+
+void tst_QInputDialog::getInteger()
+{
+ QFETCH(int, min);
+ QFETCH(int, max);
+ QVERIFY(min < max);
+ parent = new QWidget;
+ doneCode = QDialog::Accepted;
+ testFunc = &tst_QInputDialog::testFuncGetInteger;
+ startTimer(0);
+ bool ok = false;
+ const int value = min + (max - min) / 2;
+ const int result = QInputDialog::getInteger(parent, "", "", value, min, max, 1, &ok);
+ QVERIFY(ok);
+ QCOMPARE(result, value);
+ delete parent;
+}
+
+void tst_QInputDialog::getDouble_data()
+{
+ QTest::addColumn<double>("min");
+ QTest::addColumn<double>("max");
+ QTest::addColumn<int>("decimals");
+ QTest::newRow("getDouble() - - d0") << -20.0 << -10.0 << 0;
+ QTest::newRow("getDouble() - 0 d0") << -20.0 << 0.0 << 0;
+ QTest::newRow("getDouble() - + d0") << -20.0 << 20.0 << 0;
+ QTest::newRow("getDouble() 0 + d0") << 0.0 << 20.0 << 0;
+ QTest::newRow("getDouble() + + d0") << 10.0 << 20.0 << 0;
+ QTest::newRow("getDouble() - - d1") << -20.5 << -10.5 << 1;
+ QTest::newRow("getDouble() - 0 d1") << -20.5 << 0.0 << 1;
+ QTest::newRow("getDouble() - + d1") << -20.5 << 20.5 << 1;
+ QTest::newRow("getDouble() 0 + d1") << 0.0 << 20.5 << 1;
+ QTest::newRow("getDouble() + + d1") << 10.5 << 20.5 << 1;
+ QTest::newRow("getDouble() - - d2") << -20.05 << -10.05 << 2;
+ QTest::newRow("getDouble() - 0 d2") << -20.05 << 0.0 << 2;
+ QTest::newRow("getDouble() - + d2") << -20.05 << 20.05 << 2;
+ QTest::newRow("getDouble() 0 + d2") << 0.0 << 20.05 << 2;
+ QTest::newRow("getDouble() + + d2") << 10.05 << 20.05 << 2;
+}
+
+void tst_QInputDialog::getDouble()
+{
+ QFETCH(double, min);
+ QFETCH(double, max);
+ QFETCH(int, decimals);
+ QVERIFY(min < max && decimals >= 0 && decimals <= 13);
+ parent = new QWidget;
+ doneCode = QDialog::Accepted;
+ testFunc = &tst_QInputDialog::testFuncGetDouble;
+ startTimer(0);
+ bool ok = false;
+ // avoid decimals due to inconsistent roundoff behavior in QInputDialog::getDouble()
+ // (at one decimal, 10.25 is rounded off to 10.2, while at two decimals, 10.025 is
+ // rounded off to 10.03)
+ const double value = static_cast<int>(min + (max - min) / 2);
+ const double result =
+ QInputDialog::getDouble(parent, "", "", value, min, max, decimals, &ok);
+ QVERIFY(ok);
+ QCOMPARE(result, value);
+ delete parent;
+}
+
+void tst_QInputDialog::task255502getDouble()
+{
+ parent = new QWidget;
+ doneCode = QDialog::Accepted;
+ testFunc = &tst_QInputDialog::testFuncGetDouble;
+ startTimer(0);
+ bool ok = false;
+ const double value = 0.001;
+ const double result =
+ QInputDialog::getDouble(parent, "", "", value, -1, 1, 4, &ok);
+ QVERIFY(ok);
+ QCOMPARE(result, value);
+ delete parent;
+}
+
+void tst_QInputDialog::getText_data()
+{
+ QTest::addColumn<QString>("text");
+ QTest::newRow("getText() 1") << "";
+ QTest::newRow("getText() 2") << "foobar";
+ QTest::newRow("getText() 3") << " foobar";
+ QTest::newRow("getText() 4") << "foobar ";
+ QTest::newRow("getText() 5") << "aAzZ`1234567890-=~!@#$%^&*()_+[]{}\\|;:'\",.<>/?";
+}
+
+void tst_QInputDialog::getText()
+{
+ QFETCH(QString, text);
+ parent = new QWidget;
+ doneCode = QDialog::Accepted;
+ testFunc = &tst_QInputDialog::testFuncGetText;
+ startTimer(0);
+ bool ok = false;
+ const QString result = QInputDialog::getText(parent, "", "", QLineEdit::Normal, text, &ok);
+ QVERIFY(ok);
+ QCOMPARE(result, text);
+ delete parent;
+}
+
+void tst_QInputDialog::task256299_getTextReturnNullStringOnRejected()
+{
+ parent = new QWidget;
+ doneCode = QDialog::Rejected;
+ testFunc = 0;
+ startTimer(0);
+ bool ok = true;
+ const QString result = QInputDialog::getText(parent, "", "", QLineEdit::Normal, "foobar", &ok);
+ QVERIFY(!ok);
+ QVERIFY(result.isNull());
+ delete parent;
+}
+
+void tst_QInputDialog::getItem_data()
+{
+ QTest::addColumn<QStringList>("items");
+ QTest::addColumn<bool>("editable");
+ QTest::newRow("getItem() 1 true") << (QStringList() << "") << true;
+ QTest::newRow("getItem() 2 true") <<
+ (QStringList() << "spring" << "summer" << "fall" << "winter") << true;
+ QTest::newRow("getItem() 1 false") << (QStringList() << "") << false;
+ QTest::newRow("getItem() 2 false") <<
+ (QStringList() << "spring" << "summer" << "fall" << "winter") << false;
+}
+
+void tst_QInputDialog::getItem()
+{
+ QFETCH(QStringList, items);
+ QFETCH(bool, editable);
+ parent = new QWidget;
+ doneCode = QDialog::Accepted;
+ testFunc = &tst_QInputDialog::testFuncGetItem;
+ startTimer(0);
+ bool ok = false;
+ const int index = items.size() / 2;
+ const QString result = QInputDialog::getItem(parent, "", "", items, index, editable, &ok);
+ QVERIFY(ok);
+ QCOMPARE(result, items[index]);
+ delete parent;
+}
+
+void tst_QInputDialog::inputMethodHintsOfChildWidget()
+{
+ QInputDialog dialog;
+ dialog.setInputMode(QInputDialog::TextInput);
+ QList<QObject *> children = dialog.children();
+ QLineEdit *editWidget = 0;
+ for (int c = 0; c < children.size(); c++) {
+ editWidget = qobject_cast<QLineEdit *>(children.at(c));
+ if (editWidget)
+ break;
+ }
+ QVERIFY(editWidget);
+ QCOMPARE(editWidget->inputMethodHints(), dialog.inputMethodHints());
+ QCOMPARE(editWidget->inputMethodHints(), Qt::ImhNone);
+ dialog.setInputMethodHints(Qt::ImhDigitsOnly);
+ QCOMPARE(editWidget->inputMethodHints(), dialog.inputMethodHints());
+ QCOMPARE(editWidget->inputMethodHints(), Qt::ImhDigitsOnly);
+}
+
+QTEST_MAIN(tst_QInputDialog)
+#include "tst_qinputdialog.moc"
diff --git a/tests/auto/widgets/dialogs/qmessagebox/.gitignore b/tests/auto/widgets/dialogs/qmessagebox/.gitignore
new file mode 100644
index 0000000000..19a0a35121
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qmessagebox/.gitignore
@@ -0,0 +1 @@
+tst_qmessagebox
diff --git a/tests/auto/widgets/dialogs/qmessagebox/qmessagebox.pro b/tests/auto/widgets/dialogs/qmessagebox/qmessagebox.pro
new file mode 100644
index 0000000000..e3f6ddb1f6
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qmessagebox/qmessagebox.pro
@@ -0,0 +1,9 @@
+load(qttest_p4)
+TEMPLATE = app
+TARGET = tst_qmessagebox
+QT += widgets
+DEPENDPATH += .
+INCLUDEPATH += .
+
+# Input
+SOURCES += tst_qmessagebox.cpp
diff --git a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp
new file mode 100644
index 0000000000..a07d7cf7a9
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp
@@ -0,0 +1,674 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtTest/QtTest>
+#include <QMessageBox>
+#include <QDebug>
+#include <QPair>
+#include <QList>
+#include <QPointer>
+#include <QTimer>
+#include <QApplication>
+#include <QPushButton>
+#include <QDialogButtonBox>
+#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)
+#include <QMacStyle>
+#endif
+#if !defined(QT_NO_STYLE_CLEANLOOKS)
+#include <QCleanlooksStyle>
+#endif
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+#define CONVENIENCE_FUNC_SYMS(func) \
+ { \
+ int x1 = QMessageBox::func(0, "Foo", "Bar"); \
+ int x3 = QMessageBox::func(0, "Foo", "Bar", "Save"); \
+ int x6 = QMessageBox::func(0, "Foo", "Bar", "Save", "Save As"); \
+ int x7 = QMessageBox::func(0, "Foo", "Bar", "Save", "Save As", "Dont Save"); \
+ int x8 = QMessageBox::func(0, "Foo", "Bar", "Save", "Save As", "Dont Save", 1); \
+ int x9 = QMessageBox::func(0, "Foo", "Bar", "Save", "Save As", "Dont Save", 1, 2); \
+ int x10 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::YesAll, QMessageBox::Yes); \
+ int x11 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::YesAll, QMessageBox::Yes, \
+ QMessageBox::No); \
+ qDebug("%d %d %d %d %d %d %d %d", x1, x3, x6, x7, x8, x9, x10, x11); \
+ { \
+ int x4 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes, (int)QMessageBox::No); \
+ int x5 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes, (int)QMessageBox::No); \
+ int x6 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default, (int)QMessageBox::No); \
+ int x7 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes, QMessageBox::No); \
+ int x8 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes, QMessageBox::No); \
+ int x9 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No); \
+ int x10 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes, (int)QMessageBox::No, (int)QMessageBox::Ok); \
+ int x11 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes, (int)QMessageBox::No, (int)QMessageBox::Ok); \
+ int x12 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default, (int)QMessageBox::No, (int)QMessageBox::Ok); \
+ int x13 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes, QMessageBox::No, (int)QMessageBox::Ok); \
+ int x14 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes, QMessageBox::No, (int)QMessageBox::Ok); \
+ int x15 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, (int)QMessageBox::Ok); \
+ int x16 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes, (int)QMessageBox::No, QMessageBox::Ok); \
+ int x17 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes, (int)QMessageBox::No, QMessageBox::Ok); \
+ int x18 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default, (int)QMessageBox::No, QMessageBox::Ok); \
+ int x19 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes, QMessageBox::No, QMessageBox::Ok); \
+ int x20 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes, QMessageBox::No, QMessageBox::Ok); \
+ int x21 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Ok); \
+ qDebug("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21); \
+ } \
+ }
+
+#define CONVENIENCE_FUNC_SYMS_EXTRA(func) \
+ { \
+ int x1 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes); \
+ int x2 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes); \
+ int x3 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default); \
+ qDebug("%d %d %d", x1, x2, x3); \
+ }
+
+class tst_QMessageBox : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QMessageBox();
+ int exec(QMessageBox *msgBox, int key = -1);
+ void sendKeySoon();
+
+public slots:
+ void sendKey();
+
+private slots:
+ void sanityTest();
+ void defaultButton();
+ void escapeButton();
+ void button();
+ void statics();
+ void about();
+ void detailsText();
+ void detailsButtonText();
+
+#ifndef Q_WS_MAC
+ void shortcut();
+#endif
+
+ void staticSourceCompat();
+ void instanceSourceCompat();
+
+ void testSymbols();
+ void incorrectDefaultButton();
+ void updateSize();
+
+ void setInformativeText();
+ void iconPixmap();
+
+ void init();
+ void initTestCase();
+
+private:
+ int keyToSend;
+ QTimer keySendTimer;
+};
+
+tst_QMessageBox::tst_QMessageBox() : keyToSend(-1)
+{
+ int argc = qApp->argc();
+ QT_REQUIRE_VERSION(argc, qApp->argv(), "4.6.2")
+}
+
+int tst_QMessageBox::exec(QMessageBox *msgBox, int key)
+{
+ if (key == -1) {
+ QTimer::singleShot(1000, msgBox, SLOT(close()));
+ } else {
+ keyToSend = key;
+ sendKeySoon();
+ }
+ return msgBox->exec();
+}
+
+void tst_QMessageBox::sendKey()
+{
+ if (keyToSend == -2) {
+ QApplication::activeModalWidget()->close();
+ keyToSend = -1;
+ return;
+ }
+ if (keyToSend == -1)
+ return;
+ QKeyEvent *ke = new QKeyEvent(QEvent::KeyPress, keyToSend, Qt::NoModifier);
+ qApp->postEvent(QApplication::activeModalWidget(), ke);
+ keyToSend = -1;
+}
+
+void tst_QMessageBox::sendKeySoon()
+{
+ keySendTimer.start();
+}
+
+void tst_QMessageBox::init()
+{
+ // if there is any pending key send from the last test, cancel it.
+ keySendTimer.stop();
+}
+
+void tst_QMessageBox::initTestCase()
+{
+ keySendTimer.setInterval(1000);
+ keySendTimer.setSingleShot(true);
+ QVERIFY(QObject::connect(&keySendTimer, SIGNAL(timeout()), this, SLOT(sendKey())));
+}
+
+void tst_QMessageBox::sanityTest()
+{
+ QMessageBox msgBox;
+ msgBox.setText("This is insane");
+ for (int i = 0; i < 10; i++)
+ msgBox.setIcon(QMessageBox::Icon(i));
+ msgBox.setIconPixmap(QPixmap());
+ msgBox.setIconPixmap(QPixmap("whatever.png"));
+ msgBox.setTextFormat(Qt::RichText);
+ msgBox.setTextFormat(Qt::PlainText);
+ exec(&msgBox);
+}
+
+void tst_QMessageBox::button()
+{
+ QMessageBox msgBox;
+ msgBox.addButton("retry", QMessageBox::DestructiveRole);
+ QVERIFY(msgBox.button(QMessageBox::Ok) == 0); // not added yet
+ QPushButton *b1 = msgBox.addButton(QMessageBox::Ok);
+ QCOMPARE(msgBox.button(QMessageBox::Ok), (QAbstractButton *)b1); // just added
+ QCOMPARE(msgBox.standardButton(b1), QMessageBox::Ok);
+ msgBox.addButton(QMessageBox::Cancel);
+ QCOMPARE(msgBox.standardButtons(), QMessageBox::Ok | QMessageBox::Cancel);
+
+ // remove the cancel, should not exist anymore
+ msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
+ QVERIFY(msgBox.button(QMessageBox::Cancel) == 0);
+ QVERIFY(msgBox.button(QMessageBox::Yes) != 0);
+
+ // should not crash
+ QPushButton *b4 = new QPushButton;
+ msgBox.addButton(b4, QMessageBox::DestructiveRole);
+ msgBox.addButton(0, QMessageBox::ActionRole);
+}
+
+void tst_QMessageBox::defaultButton()
+{
+ QMessageBox msgBox;
+ QVERIFY(msgBox.defaultButton() == 0);
+ msgBox.addButton(QMessageBox::Ok);
+ msgBox.addButton(QMessageBox::Cancel);
+ QVERIFY(msgBox.defaultButton() == 0);
+ QPushButton pushButton;
+ msgBox.setDefaultButton(&pushButton);
+ QVERIFY(msgBox.defaultButton() == 0); // we have not added it yet
+ QPushButton *retryButton = msgBox.addButton(QMessageBox::Retry);
+ msgBox.setDefaultButton(retryButton);
+ QCOMPARE(msgBox.defaultButton(), retryButton);
+ exec(&msgBox);
+ QCOMPARE(msgBox.clickedButton(), msgBox.button(QMessageBox::Cancel));
+
+ exec(&msgBox, Qt::Key_Enter);
+ QCOMPARE(msgBox.clickedButton(), (QAbstractButton *)retryButton);
+
+ QAbstractButton *okButton = msgBox.button(QMessageBox::Ok);
+ msgBox.setDefaultButton(QMessageBox::Ok);
+ QCOMPARE(msgBox.defaultButton(), (QPushButton *)okButton);
+ exec(&msgBox, Qt::Key_Enter);
+ QCOMPARE(msgBox.clickedButton(), okButton);
+ msgBox.setDefaultButton(QMessageBox::Yes); // its not in there!
+ QVERIFY(msgBox.defaultButton() == okButton);
+ msgBox.removeButton(okButton);
+ delete okButton;
+ okButton = 0;
+ QVERIFY(msgBox.defaultButton() == 0);
+ msgBox.setDefaultButton(QMessageBox::Ok);
+ QVERIFY(msgBox.defaultButton() == 0);
+}
+
+void tst_QMessageBox::escapeButton()
+{
+ QMessageBox msgBox;
+ QVERIFY(msgBox.escapeButton() == 0);
+ msgBox.addButton(QMessageBox::Ok);
+ exec(&msgBox);
+ QVERIFY(msgBox.clickedButton() == msgBox.button(QMessageBox::Ok)); // auto detected (one button only)
+ msgBox.addButton(QMessageBox::Cancel);
+ QVERIFY(msgBox.escapeButton() == 0);
+ QPushButton invalidButton;
+ msgBox.setEscapeButton(&invalidButton);
+ QVERIFY(msgBox.escapeButton() == 0);
+ QAbstractButton *retryButton = msgBox.addButton(QMessageBox::Retry);
+
+ exec(&msgBox);
+ QVERIFY(msgBox.clickedButton() == msgBox.button(QMessageBox::Cancel)); // auto detected (cancel)
+
+ msgBox.setEscapeButton(retryButton);
+ QCOMPARE(msgBox.escapeButton(), (QAbstractButton *)retryButton);
+
+ // with escape
+ exec(&msgBox, Qt::Key_Escape);
+ QCOMPARE(msgBox.clickedButton(), retryButton);
+
+ // with close
+ exec(&msgBox);
+ QCOMPARE(msgBox.clickedButton(), (QAbstractButton *)retryButton);
+
+ QAbstractButton *okButton = msgBox.button(QMessageBox::Ok);
+ msgBox.setEscapeButton(QMessageBox::Ok);
+ QCOMPARE(msgBox.escapeButton(), okButton);
+ exec(&msgBox, Qt::Key_Escape);
+ QCOMPARE(msgBox.clickedButton(), okButton);
+ msgBox.setEscapeButton(QMessageBox::Yes); // its not in there!
+ QVERIFY(msgBox.escapeButton() == okButton);
+ msgBox.removeButton(okButton);
+ delete okButton;
+ okButton = 0;
+ QVERIFY(msgBox.escapeButton() == 0);
+ msgBox.setEscapeButton(QMessageBox::Ok);
+ QVERIFY(msgBox.escapeButton() == 0);
+
+ QMessageBox msgBox2;
+ msgBox2.addButton(QMessageBox::Yes);
+ msgBox2.addButton(QMessageBox::No);
+ exec(&msgBox2);
+ QVERIFY(msgBox2.clickedButton() == msgBox2.button(QMessageBox::No)); // auto detected (one No button only)
+
+ QPushButton *rejectButton = new QPushButton;
+ msgBox2.addButton(rejectButton, QMessageBox::RejectRole);
+ exec(&msgBox2);
+ QVERIFY(msgBox2.clickedButton() == rejectButton); // auto detected (one reject button only)
+
+ msgBox2.addButton(new QPushButton, QMessageBox::RejectRole);
+ exec(&msgBox2);
+ QVERIFY(msgBox2.clickedButton() == msgBox2.button(QMessageBox::No)); // auto detected (one No button only)
+}
+
+void tst_QMessageBox::statics()
+{
+ QMessageBox::StandardButton (*statics[4])(QWidget *, const QString &,
+ const QString&, QMessageBox::StandardButtons buttons,
+ QMessageBox::StandardButton);
+
+ statics[0] = QMessageBox::information;
+ statics[1] = QMessageBox::critical;
+ statics[2] = QMessageBox::question;
+ statics[3] = QMessageBox::warning;
+
+ for (int i = 0; i < 4; i++) {
+ keyToSend = Qt::Key_Escape;
+ sendKeySoon();
+ QMessageBox::StandardButton sb = (*statics[i])(0, "caption",
+ "text", QMessageBox::Yes | QMessageBox::No | QMessageBox::Help | QMessageBox::Cancel,
+ QMessageBox::NoButton);
+ QCOMPARE(sb, QMessageBox::Cancel);
+ QCOMPARE(keyToSend, -1);
+
+ keyToSend = -2; // close()
+ sendKeySoon();
+ sb = (*statics[i])(0, "caption",
+ "text", QMessageBox::Yes | QMessageBox::No | QMessageBox::Help | QMessageBox::Cancel,
+ QMessageBox::NoButton);
+ QCOMPARE(sb, QMessageBox::Cancel);
+ QCOMPARE(keyToSend, -1);
+
+ keyToSend = Qt::Key_Enter;
+ sendKeySoon();
+ sb = (*statics[i])(0, "caption",
+ "text", QMessageBox::Yes | QMessageBox::No | QMessageBox::Help,
+ QMessageBox::Yes);
+ QCOMPARE(sb, QMessageBox::Yes);
+ QCOMPARE(keyToSend, -1);
+
+ keyToSend = Qt::Key_Enter;
+ sendKeySoon();
+ sb = (*statics[i])(0, "caption",
+ "text", QMessageBox::Yes | QMessageBox::No | QMessageBox::Help,
+ QMessageBox::No);
+ QCOMPARE(sb, QMessageBox::No);
+ QCOMPARE(keyToSend, -1);
+ }
+}
+
+// Shortcuts are not used on Mac OS X.
+#ifndef Q_WS_MAC
+void tst_QMessageBox::shortcut()
+{
+ QMessageBox msgBox;
+ msgBox.addButton("O&k", QMessageBox::YesRole);
+ msgBox.addButton("&No", QMessageBox::YesRole);
+ msgBox.addButton("&Maybe", QMessageBox::YesRole);
+ QCOMPARE(exec(&msgBox, Qt::Key_M), 2);
+}
+#endif
+
+void tst_QMessageBox::about()
+{
+ keyToSend = Qt::Key_Escape;
+ sendKeySoon();
+ QMessageBox::about(0, "Caption", "This is an auto test");
+ // On Mac, about and aboutQt are not modal, so we need to
+ // explicitly run the event loop
+#ifdef Q_WS_MAC
+ QTRY_COMPARE(keyToSend, -1);
+#else
+ QCOMPARE(keyToSend, -1);
+#endif
+
+#if !defined(Q_OS_WINCE)
+ keyToSend = Qt::Key_Enter;
+#else
+ keyToSend = Qt::Key_Escape;
+#endif
+ sendKeySoon();
+ QMessageBox::aboutQt(0, "Caption");
+#ifdef Q_WS_MAC
+ QTRY_COMPARE(keyToSend, -1);
+#else
+ QCOMPARE(keyToSend, -1);
+#endif
+}
+
+void tst_QMessageBox::staticSourceCompat()
+{
+ int ret;
+
+ // source compat tests for < 4.2
+ keyToSend = Qt::Key_Enter;
+ sendKeySoon();
+ ret = QMessageBox::information(0, "title", "text", QMessageBox::Yes, QMessageBox::No);
+ int expectedButton = int(QMessageBox::Yes);
+#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)
+ if (qobject_cast<QMacStyle *>(qApp->style()))
+ expectedButton = int(QMessageBox::No);
+#elif !defined(QT_NO_STYLE_CLEANLOOKS)
+ if (qobject_cast<QCleanlooksStyle *>(qApp->style()))
+ expectedButton = int(QMessageBox::No);
+#endif
+ QCOMPARE(ret, expectedButton);
+ QCOMPARE(keyToSend, -1);
+
+ keyToSend = Qt::Key_Enter;
+ sendKeySoon();
+ ret = QMessageBox::information(0, "title", "text", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No);
+ QCOMPARE(ret, int(QMessageBox::Yes));
+ QCOMPARE(keyToSend, -1);
+
+ keyToSend = Qt::Key_Enter;
+ sendKeySoon();
+ ret = QMessageBox::information(0, "title", "text", QMessageBox::Yes, QMessageBox::No | QMessageBox::Default);
+ QCOMPARE(ret, int(QMessageBox::No));
+ QCOMPARE(keyToSend, -1);
+
+ keyToSend = Qt::Key_Enter;
+ sendKeySoon();
+ ret = QMessageBox::information(0, "title", "text", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No | QMessageBox::Escape);
+ QCOMPARE(ret, int(QMessageBox::Yes));
+ QCOMPARE(keyToSend, -1);
+
+ keyToSend = Qt::Key_Enter;
+ sendKeySoon();
+ ret = QMessageBox::information(0, "title", "text", QMessageBox::Yes | QMessageBox::Escape, QMessageBox::No | QMessageBox::Default);
+ QCOMPARE(ret, int(QMessageBox::No));
+ QCOMPARE(keyToSend, -1);
+
+ // the button text versions
+ keyToSend = Qt::Key_Enter;
+ sendKeySoon();
+ ret = QMessageBox::information(0, "title", "text", "Yes", "No", QString(), 1);
+ QCOMPARE(ret, 1);
+ QCOMPARE(keyToSend, -1);
+
+ if (0) { // dont run these tests since the dialog wont close!
+ keyToSend = Qt::Key_Escape;
+ sendKeySoon();
+ ret = QMessageBox::information(0, "title", "text", "Yes", "No", QString(), 1);
+ QCOMPARE(ret, -1);
+ QCOMPARE(keyToSend, -1);
+
+ keyToSend = Qt::Key_Escape;
+ sendKeySoon();
+ ret = QMessageBox::information(0, "title", "text", "Yes", "No", QString(), 0, 1);
+ QCOMPARE(ret, 1);
+ QCOMPARE(keyToSend, -1);
+ }
+}
+
+void tst_QMessageBox::instanceSourceCompat()
+{
+ QMessageBox mb("Application name here",
+ "Saving the file will overwrite the original file on the disk.\n"
+ "Do you really want to save?",
+ QMessageBox::Information,
+ QMessageBox::Yes | QMessageBox::Default,
+ QMessageBox::No,
+ QMessageBox::Cancel | QMessageBox::Escape);
+ mb.setButtonText(QMessageBox::Yes, "Save");
+ mb.setButtonText(QMessageBox::No, "Discard");
+ mb.addButton("&Revert", QMessageBox::RejectRole);
+ mb.addButton("&Zoo", QMessageBox::ActionRole);
+
+ QCOMPARE(exec(&mb, Qt::Key_Enter), int(QMessageBox::Yes));
+ QCOMPARE(exec(&mb, Qt::Key_Escape), int(QMessageBox::Cancel));
+#ifndef Q_WS_MAC
+ // mnemonics are not used on Mac OS X
+ QCOMPARE(exec(&mb, Qt::ALT + Qt::Key_R), 0);
+ QCOMPARE(exec(&mb, Qt::ALT + Qt::Key_Z), 1);
+#endif
+}
+
+void tst_QMessageBox::testSymbols()
+{
+ return;
+
+ QMessageBox::Icon icon;
+ icon = QMessageBox::NoIcon;
+ icon = QMessageBox::Information;
+ icon = QMessageBox::Warning;
+ icon = QMessageBox::Critical;
+ icon = QMessageBox::Question;
+
+ QMessageBox mb1;
+ QMessageBox mb2(0);
+ QMessageBox mb3(&mb1);
+ QMessageBox mb3b("title", "text", QMessageBox::Critical, int(QMessageBox::Yes),
+ int(QMessageBox::No), int(QMessageBox::Cancel), &mb1, Qt::Dialog);
+
+ QMessageBox::Button button = QMessageBox::NoButton;
+ button = QMessageBox::Ok;
+ button = QMessageBox::Cancel;
+ button = QMessageBox::Yes;
+ button = QMessageBox::No;
+ button = QMessageBox::Abort;
+ button = QMessageBox::Retry;
+ button = QMessageBox::Ignore;
+ button = QMessageBox::YesAll;
+ button = QMessageBox::NoAll;
+ button = QMessageBox::ButtonMask;
+ button = QMessageBox::Default;
+ button = QMessageBox::Escape;
+ button = QMessageBox::FlagMask;
+
+ const QString text = QStringLiteral("Foo");
+ mb1.setText(text);
+ QCOMPARE(mb1.text(), text);
+
+ icon = mb1.icon();
+ QVERIFY(icon == QMessageBox::NoIcon);
+ mb1.setIcon(QMessageBox::Question);
+ QVERIFY(mb1.icon() == QMessageBox::Question);
+
+ QPixmap iconPixmap = mb1.iconPixmap();
+ mb1.setIconPixmap(iconPixmap);
+ QVERIFY(mb1.icon() == QMessageBox::NoIcon);
+
+ QCOMPARE(mb1.buttonText(QMessageBox::Ok), QLatin1String("OK"));
+ QCOMPARE(mb1.buttonText(QMessageBox::Cancel), QString());
+ QCOMPARE(mb1.buttonText(QMessageBox::Ok | QMessageBox::Default), QString());
+
+ const QString button1 = QStringLiteral("Bar");
+ mb2.setButtonText(QMessageBox::Cancel, QStringLiteral("Foo"));
+ mb2.setButtonText(QMessageBox::Ok, button1);
+ mb2.setButtonText(QMessageBox::Ok | QMessageBox::Default, QStringLiteral("Baz"));
+
+ QCOMPARE(mb2.buttonText(QMessageBox::Cancel), QString());
+ QCOMPARE(mb2.buttonText(QMessageBox::Ok), button1);
+
+ QVERIFY(mb3b.buttonText(QMessageBox::Yes).endsWith("Yes"));
+ QCOMPARE(mb3b.buttonText(QMessageBox::YesAll), QString());
+ QCOMPARE(mb3b.buttonText(QMessageBox::Ok), QString());
+
+ const QString button2 = QStringLiteral("Blah");
+ mb3b.setButtonText(QMessageBox::Yes, button2);
+ mb3b.setButtonText(QMessageBox::YesAll, QStringLiteral("Zoo"));
+ mb3b.setButtonText(QMessageBox::Ok, QStringLiteral("Zoo"));
+
+ QCOMPARE(mb3b.buttonText(QMessageBox::Yes), button2);
+ QCOMPARE(mb3b.buttonText(QMessageBox::YesAll), QString());
+ QCOMPARE(mb3b.buttonText(QMessageBox::Ok), QString());
+
+ QCOMPARE(mb1.textFormat(), Qt::AutoText);
+ mb1.setTextFormat(Qt::PlainText);
+ QCOMPARE(mb1.textFormat(), Qt::PlainText);
+
+ CONVENIENCE_FUNC_SYMS(information);
+ CONVENIENCE_FUNC_SYMS_EXTRA(information);
+ CONVENIENCE_FUNC_SYMS(question);
+ CONVENIENCE_FUNC_SYMS_EXTRA(question);
+ CONVENIENCE_FUNC_SYMS(warning);
+ CONVENIENCE_FUNC_SYMS(critical);
+
+ QSize sizeHint = mb1.sizeHint();
+ QVERIFY(sizeHint.width() > 20 && sizeHint.height() > 20);
+
+ QMessageBox::about(&mb1, "title", "text");
+ QMessageBox::aboutQt(&mb1);
+ QMessageBox::aboutQt(&mb1, "title");
+}
+
+void tst_QMessageBox::detailsText()
+{
+ QMessageBox box;
+ QString text("This is the details text.");
+ box.setDetailedText(text);
+ QCOMPARE(box.detailedText(), text);
+}
+
+void tst_QMessageBox::detailsButtonText()
+{
+ QMessageBox box;
+ box.setDetailedText("bla");
+ box.open();
+ QApplication::postEvent(&box, new QEvent(QEvent::LanguageChange));
+ QApplication::processEvents();
+ QDialogButtonBox* bb = box.findChild<QDialogButtonBox*>("qt_msgbox_buttonbox");
+ QVERIFY(bb); //get the detail button
+
+ QList<QAbstractButton *> list = bb->buttons();
+ QAbstractButton* btn = NULL;
+ foreach(btn, list) {
+ if (btn && (btn->inherits("QPushButton"))) {
+ if (btn->text() != QMessageBox::tr("OK") && btn->text() != QMessageBox::tr("Show Details...")) {
+ QFAIL(qPrintable(QString("Unexpected messagebox button text: %1").arg(btn->text())));
+ }
+ }
+ }
+}
+
+void tst_QMessageBox::incorrectDefaultButton()
+{
+ keyToSend = Qt::Key_Escape;
+ sendKeySoon();
+ //Do not crash here
+ QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added");
+ QMessageBox::question( 0, "", "I've been hit!",QMessageBox::Ok | QMessageBox::Cancel,QMessageBox::Save );
+ QCOMPARE(keyToSend, -1);
+
+ keyToSend = Qt::Key_Escape;
+ sendKeySoon();
+ QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added");
+ QMessageBox::question( 0, "", "I've been hit!",QFlag(QMessageBox::Ok | QMessageBox::Cancel),QMessageBox::Save );
+ QCOMPARE(keyToSend, -1);
+
+ keyToSend = Qt::Key_Escape;
+ sendKeySoon();
+ QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added");
+ QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added");
+ //do not crash here -> call old function of QMessageBox in this case
+ QMessageBox::question( 0, "", "I've been hit!",QMessageBox::Ok | QMessageBox::Cancel,QMessageBox::Save | QMessageBox::Cancel,QMessageBox::Ok);
+ QCOMPARE(keyToSend, -1);
+}
+
+void tst_QMessageBox::updateSize()
+{
+ QMessageBox box;
+ box.setText("This is awesome");
+ box.show();
+ QSize oldSize = box.size();
+ QString longText;
+ for (int i = 0; i < 20; i++)
+ longText += box.text();
+ box.setText(longText);
+ QVERIFY(box.size() != oldSize); // should have grown
+ QVERIFY(box.width() > oldSize.width() || box.height() > oldSize.height());
+ oldSize = box.size();
+ box.setStandardButtons(QMessageBox::StandardButtons(0xFFFF));
+ QVERIFY(box.size() != oldSize); // should have grown
+ QVERIFY(box.width() > oldSize.width() || box.height() > oldSize.height());
+}
+
+void tst_QMessageBox::setInformativeText()
+{
+ QMessageBox msgbox(QMessageBox::Warning, "", "", QMessageBox::Ok);
+ QString itext = "This is a very long message and it should make the dialog have enough width to fit this message in";
+ msgbox.setInformativeText(itext);
+ msgbox.show();
+ QCOMPARE(msgbox.informativeText(), itext);
+ QVERIFY2(msgbox.width() > 190, //verify it's big enough (task181688)
+ qPrintable(QString("%1 > 190").arg(msgbox.width())));
+}
+
+void tst_QMessageBox::iconPixmap()
+{
+ QMessageBox messageBox;
+ QCOMPARE(messageBox.iconPixmap(), QPixmap());
+}
+
+QTEST_MAIN(tst_QMessageBox)
+#include "tst_qmessagebox.moc"
diff --git a/tests/auto/widgets/dialogs/qprogressdialog/.gitignore b/tests/auto/widgets/dialogs/qprogressdialog/.gitignore
new file mode 100644
index 0000000000..ce3cd0d7dd
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qprogressdialog/.gitignore
@@ -0,0 +1 @@
+tst_qprogressdialog
diff --git a/tests/auto/widgets/dialogs/qprogressdialog/qprogressdialog.pro b/tests/auto/widgets/dialogs/qprogressdialog/qprogressdialog.pro
new file mode 100644
index 0000000000..f3861e4cd3
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qprogressdialog/qprogressdialog.pro
@@ -0,0 +1,9 @@
+############################################################
+# Project file for autotest for file qprogressdialog.h
+############################################################
+
+load(qttest_p4)
+QT += widgets
+SOURCES += tst_qprogressdialog.cpp
+
+
diff --git a/tests/auto/widgets/dialogs/qprogressdialog/tst_qprogressdialog.cpp b/tests/auto/widgets/dialogs/qprogressdialog/tst_qprogressdialog.cpp
new file mode 100644
index 0000000000..5fbd5d747a
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qprogressdialog/tst_qprogressdialog.cpp
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+#include <qcoreapplication.h>
+#include <qdebug.h>
+#include <qprogressdialog.h>
+#include <qlabel.h>
+
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QProgressDialog : public QObject
+{
+Q_OBJECT
+
+public:
+ tst_QProgressDialog();
+ virtual ~tst_QProgressDialog();
+
+private slots:
+ void getSetCheck();
+ void task198202();
+};
+
+tst_QProgressDialog::tst_QProgressDialog()
+{
+}
+
+tst_QProgressDialog::~tst_QProgressDialog()
+{
+}
+
+// Testing get/set functions
+void tst_QProgressDialog::getSetCheck()
+{
+ QProgressDialog obj1;
+ // bool QProgressDialog::autoReset()
+ // void QProgressDialog::setAutoReset(bool)
+ obj1.setAutoReset(false);
+ QCOMPARE(false, obj1.autoReset());
+ obj1.setAutoReset(true);
+ QCOMPARE(true, obj1.autoReset());
+
+ // bool QProgressDialog::autoClose()
+ // void QProgressDialog::setAutoClose(bool)
+ obj1.setAutoClose(false);
+ QCOMPARE(false, obj1.autoClose());
+ obj1.setAutoClose(true);
+ QCOMPARE(true, obj1.autoClose());
+
+ // int QProgressDialog::maximum()
+ // void QProgressDialog::setMaximum(int)
+ obj1.setMaximum(0);
+ QCOMPARE(0, obj1.maximum());
+ obj1.setMaximum(INT_MIN);
+ QCOMPARE(INT_MIN, obj1.maximum());
+ obj1.setMaximum(INT_MAX);
+ QCOMPARE(INT_MAX, obj1.maximum());
+
+ // int QProgressDialog::minimum()
+ // void QProgressDialog::setMinimum(int)
+ obj1.setMinimum(0);
+ QCOMPARE(0, obj1.minimum());
+ obj1.setMinimum(INT_MIN);
+ QCOMPARE(INT_MIN, obj1.minimum());
+ obj1.setMinimum(INT_MAX);
+ QCOMPARE(INT_MAX, obj1.minimum());
+
+ // int QProgressDialog::value()
+ // void QProgressDialog::setValue(int)
+ obj1.setMaximum(INT_MAX);
+ obj1.setMinimum(INT_MIN);
+ obj1.setValue(0);
+ QCOMPARE(0, obj1.value());
+ obj1.setValue(INT_MIN+1);
+ QCOMPARE(INT_MIN+1, obj1.value());
+ obj1.setValue(INT_MIN);
+ QCOMPARE(INT_MIN, obj1.value());
+ obj1.setValue(INT_MAX-1);
+ QCOMPARE(INT_MAX-1, obj1.value());
+
+ obj1.setValue(INT_MAX);
+ QCOMPARE(INT_MIN, obj1.value()); // We set autoReset, the thing is reset
+
+ obj1.setAutoReset(false);
+ obj1.setValue(INT_MAX);
+ QCOMPARE(INT_MAX, obj1.value());
+ obj1.setAutoReset(true);
+
+ // int QProgressDialog::minimumDuration()
+ // void QProgressDialog::setMinimumDuration(int)
+ obj1.setMinimumDuration(0);
+ QCOMPARE(0, obj1.minimumDuration());
+ obj1.setMinimumDuration(INT_MIN);
+ QCOMPARE(INT_MIN, obj1.minimumDuration());
+ obj1.setMinimumDuration(INT_MAX);
+ QCOMPARE(INT_MAX, obj1.minimumDuration());
+}
+
+void tst_QProgressDialog::task198202()
+{
+ //should not crash
+ QProgressDialog dlg(QLatin1String("test"),QLatin1String("test"),1,10);
+ dlg.show();
+ QTest::qWait(20);
+ int futureHeight = dlg.sizeHint().height() - qFindChild<QLabel*>(&dlg)->sizeHint().height();
+ dlg.setLabel(0);
+ QTest::ignoreMessage(QtWarningMsg, "QProgressDialog::setBar: Cannot set a null progress bar");
+ dlg.setBar(0);
+ QTest::qWait(20);
+ QCOMPARE(dlg.sizeHint().height(), futureHeight);
+}
+
+QTEST_MAIN(tst_QProgressDialog)
+#include "tst_qprogressdialog.moc"
diff --git a/tests/auto/widgets/dialogs/qsidebar/.gitignore b/tests/auto/widgets/dialogs/qsidebar/.gitignore
new file mode 100644
index 0000000000..194ca9f244
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qsidebar/.gitignore
@@ -0,0 +1 @@
+tst_qsidebar
diff --git a/tests/auto/widgets/dialogs/qsidebar/qsidebar.pro b/tests/auto/widgets/dialogs/qsidebar/qsidebar.pro
new file mode 100644
index 0000000000..9f6e094784
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qsidebar/qsidebar.pro
@@ -0,0 +1,6 @@
+CONFIG += qttest_p4
+
+QT += core-private
+QT += widgets widgets-private
+SOURCES += tst_qsidebar.cpp
+TARGET = tst_qsidebar
diff --git a/tests/auto/widgets/dialogs/qsidebar/tst_qsidebar.cpp b/tests/auto/widgets/dialogs/qsidebar/tst_qsidebar.cpp
new file mode 100644
index 0000000000..912719f76a
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qsidebar/tst_qsidebar.cpp
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include "../../../src/widgets/dialogs/qsidebar_p.h"
+#include "../../../src/widgets/dialogs/qfilesystemmodel_p.h"
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QSidebar : public QObject {
+ Q_OBJECT
+
+public:
+ tst_QSidebar();
+ virtual ~tst_QSidebar();
+
+public Q_SLOTS:
+ void init();
+ void cleanup();
+
+private slots:
+ void setUrls();
+ void selectUrls();
+ void addUrls();
+
+ void goToUrl();
+};
+
+tst_QSidebar::tst_QSidebar()
+{
+}
+
+tst_QSidebar::~tst_QSidebar()
+{
+}
+
+void tst_QSidebar::init()
+{
+}
+
+void tst_QSidebar::cleanup()
+{
+}
+
+void tst_QSidebar::setUrls()
+{
+ QList<QUrl> urls;
+ QFileSystemModel fsmodel;
+ QSidebar qsidebar;
+ qsidebar.init(&fsmodel, urls);
+ QAbstractItemModel *model = qsidebar.model();
+
+ urls << QUrl::fromLocalFile(QDir::rootPath())
+ << QUrl::fromLocalFile(QDir::temp().absolutePath());
+
+ QCOMPARE(model->rowCount(), 0);
+ qsidebar.setUrls(urls);
+ QCOMPARE(qsidebar.urls(), urls);
+ QCOMPARE(model->rowCount(), urls.count());
+ qsidebar.setUrls(urls);
+ QCOMPARE(model->rowCount(), urls.count());
+}
+
+void tst_QSidebar::selectUrls()
+{
+ QList<QUrl> urls;
+ urls << QUrl::fromLocalFile(QDir::rootPath())
+ << QUrl::fromLocalFile(QDir::temp().absolutePath());
+ QFileSystemModel fsmodel;
+ QSidebar qsidebar;
+ qsidebar.init(&fsmodel, urls);
+
+ QSignalSpy spy(&qsidebar, SIGNAL(goToUrl(const QUrl &)));
+ qsidebar.selectUrl(urls.at(0));
+ QCOMPARE(spy.count(), 0);
+}
+
+void tst_QSidebar::addUrls()
+{
+ QList<QUrl> emptyUrls;
+ QFileSystemModel fsmodel;
+ QSidebar qsidebar;
+ qsidebar.init(&fsmodel, emptyUrls);
+ QAbstractItemModel *model = qsidebar.model();
+ QDir testDir = QDir::home();
+
+ // default
+ QCOMPARE(model->rowCount(), 0);
+
+ QList<QUrl> urls;
+ urls << QUrl::fromLocalFile(QDir::rootPath())
+ << QUrl::fromLocalFile(QDir::temp().absolutePath());
+
+ // test < 0
+ qsidebar.addUrls(urls, -1);
+ QCOMPARE(model->rowCount(), 2);
+
+ // test = 0
+ qsidebar.setUrls(emptyUrls);
+ qsidebar.addUrls(urls, 0);
+ QCOMPARE(model->rowCount(), 2);
+
+ // test > 0
+ qsidebar.setUrls(emptyUrls);
+ qsidebar.addUrls(urls, 100);
+ QCOMPARE(model->rowCount(), 2);
+
+ // test inserting with already existing rows
+ QList<QUrl> moreUrls;
+ moreUrls << QUrl::fromLocalFile(testDir.absolutePath());
+ qsidebar.addUrls(moreUrls, -1);
+ QCOMPARE(model->rowCount(), 3);
+
+ // make sure invalid urls are still added
+ QList<QUrl> badUrls;
+ badUrls << QUrl::fromLocalFile(testDir.absolutePath() + "/I used to exist");
+ qsidebar.addUrls(badUrls, 0);
+ QCOMPARE(model->rowCount(), 4);
+
+ // check that every item has text and an icon including the above invalid one
+ for (int i = 0; i < model->rowCount(); ++i) {
+ QVERIFY(!model->index(i, 0).data().toString().isEmpty());
+ QIcon icon = qvariant_cast<QIcon>(model->index(i, 0).data(Qt::DecorationRole));
+ QVERIFY(!icon.isNull());
+ }
+
+ // test moving up the list
+ qsidebar.setUrls(emptyUrls);
+ qsidebar.addUrls(urls, 100);
+ qsidebar.addUrls(moreUrls, 100);
+ QCOMPARE(model->rowCount(), 3);
+ qsidebar.addUrls(moreUrls, 1);
+ QCOMPARE(qsidebar.urls()[1], moreUrls[0]);
+
+ // test appending with -1
+ qsidebar.setUrls(emptyUrls);
+ qsidebar.addUrls(urls, -1);
+ qsidebar.addUrls(moreUrls, -1);
+ QCOMPARE(qsidebar.urls()[0], urls[0]);
+
+ QList<QUrl> doubleUrls;
+ //tow exact same paths, we have only one entry
+ doubleUrls << QUrl::fromLocalFile(testDir.absolutePath());
+ doubleUrls << QUrl::fromLocalFile(testDir.absolutePath());
+ qsidebar.setUrls(emptyUrls);
+ qsidebar.addUrls(doubleUrls, 1);
+ QCOMPARE(qsidebar.urls().size(), 1);
+
+ // Two paths that are effectively pointing to the same location
+ doubleUrls << QUrl::fromLocalFile(testDir.absolutePath());
+ doubleUrls << QUrl::fromLocalFile(testDir.absolutePath() + "/.");
+ qsidebar.setUrls(emptyUrls);
+ qsidebar.addUrls(doubleUrls, 1);
+ QCOMPARE(qsidebar.urls().size(), 1);
+
+#if defined(Q_OS_WIN)
+ //Windows is case insensitive so no duplicate entries in that case
+ doubleUrls << QUrl::fromLocalFile(testDir.absolutePath());
+ doubleUrls << QUrl::fromLocalFile(testDir.absolutePath().toUpper());
+ qsidebar.setUrls(emptyUrls);
+ qsidebar.addUrls(doubleUrls, 1);
+ QCOMPARE(qsidebar.urls().size(), 1);
+#else
+ //Two different paths we should have two entries
+ doubleUrls << QUrl::fromLocalFile(testDir.absolutePath());
+ doubleUrls << QUrl::fromLocalFile(testDir.absolutePath().toUpper());
+ qsidebar.setUrls(emptyUrls);
+ qsidebar.addUrls(doubleUrls, 1);
+ QCOMPARE(qsidebar.urls().size(), 2);
+#endif
+}
+
+void tst_QSidebar::goToUrl()
+{
+ QList<QUrl> urls;
+ urls << QUrl::fromLocalFile(QDir::rootPath())
+ << QUrl::fromLocalFile(QDir::temp().absolutePath());
+ QFileSystemModel fsmodel;
+ QSidebar qsidebar;
+ qsidebar.init(&fsmodel, urls);
+ qsidebar.show();
+
+ QSignalSpy spy(&qsidebar, SIGNAL(goToUrl(const QUrl &)));
+ QTest::mousePress(qsidebar.viewport(), Qt::LeftButton, 0, qsidebar.visualRect(qsidebar.model()->index(0, 0)).center());
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE((spy.value(0)).at(0).toUrl(), urls.first());
+}
+
+QTEST_MAIN(tst_QSidebar)
+#include "tst_qsidebar.moc"
+
diff --git a/tests/auto/widgets/dialogs/qwizard/.gitignore b/tests/auto/widgets/dialogs/qwizard/.gitignore
new file mode 100644
index 0000000000..9494c96da2
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qwizard/.gitignore
@@ -0,0 +1 @@
+tst_qwizard
diff --git a/tests/auto/widgets/dialogs/qwizard/images/background.png b/tests/auto/widgets/dialogs/qwizard/images/background.png
new file mode 100644
index 0000000000..db7d67dc3d
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qwizard/images/background.png
Binary files differ
diff --git a/tests/auto/widgets/dialogs/qwizard/images/banner.png b/tests/auto/widgets/dialogs/qwizard/images/banner.png
new file mode 100644
index 0000000000..be36202d99
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qwizard/images/banner.png
Binary files differ
diff --git a/tests/auto/widgets/dialogs/qwizard/images/logo.png b/tests/auto/widgets/dialogs/qwizard/images/logo.png
new file mode 100644
index 0000000000..9cf3350c4b
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qwizard/images/logo.png
Binary files differ
diff --git a/tests/auto/widgets/dialogs/qwizard/images/watermark.png b/tests/auto/widgets/dialogs/qwizard/images/watermark.png
new file mode 100644
index 0000000000..9305675549
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qwizard/images/watermark.png
Binary files differ
diff --git a/tests/auto/widgets/dialogs/qwizard/qwizard.pro b/tests/auto/widgets/dialogs/qwizard/qwizard.pro
new file mode 100644
index 0000000000..c27801b82f
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qwizard/qwizard.pro
@@ -0,0 +1,4 @@
+load(qttest_p4)
+QT += widgets
+SOURCES += tst_qwizard.cpp
+RESOURCES = qwizard.qrc
diff --git a/tests/auto/widgets/dialogs/qwizard/qwizard.qrc b/tests/auto/widgets/dialogs/qwizard/qwizard.qrc
new file mode 100644
index 0000000000..471da9def6
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qwizard/qwizard.qrc
@@ -0,0 +1,8 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>images/background.png</file>
+ <file>images/banner.png</file>
+ <file>images/logo.png</file>
+ <file>images/watermark.png</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
new file mode 100644
index 0000000000..2e05eb5bab
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
@@ -0,0 +1,2645 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QFont>
+#include <QtTest/QtTest>
+#include <QCheckBox>
+#include <QLabel>
+#include <QLineEdit>
+#include <QList>
+#include <QPushButton>
+#include <QToolButton>
+#include <QVBoxLayout>
+#include <QWizard>
+#include <QStyle>
+#include <QPlastiqueStyle>
+#include <QTreeWidget>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+static QImage grabWidget(QWidget *window)
+{
+ return QPixmap::grabWidget(window).toImage();
+}
+
+class tst_QWizard : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QWizard();
+
+public slots:
+ void init();
+ void cleanup();
+
+private slots:
+ void buttonText();
+ void setButtonLayout();
+ void setButton();
+ void setTitleFormatEtc();
+ void setPixmap();
+ void setDefaultProperty();
+ void addPage();
+ void setPage();
+ void setStartId();
+ void setOption_IndependentPages();
+ void setOption_IgnoreSubTitles();
+ void setOption_ExtendedWatermarkPixmap();
+ void setOption_NoDefaultButton();
+ void setOption_NoBackButtonOnStartPage();
+ void setOption_NoBackButtonOnLastPage();
+ void setOption_DisabledBackButtonOnLastPage();
+ void setOption_HaveNextButtonOnLastPage();
+ void setOption_HaveFinishButtonOnEarlyPages();
+ void setOption_NoCancelButton();
+ void setOption_CancelButtonOnLeft();
+ void setOption_HaveHelpButton();
+ void setOption_HelpButtonOnRight();
+ void setOption_HaveCustomButtonX();
+#ifndef Q_OS_WINCE
+ void combinations_data();
+ void combinations();
+#endif
+ void showCurrentPageOnly();
+ void setButtonText();
+ void setCommitPage();
+ void setWizardStyle();
+ void removePage();
+ void sideWidget();
+
+ // task-specific tests below me:
+ void task161660_buttonSpacing();
+ void task177716_disableCommitButton();
+ void task183550_stretchFactor();
+ void task161658_alignments();
+ void task177022_setFixedSize();
+ void task248107_backButton();
+ void task255350_fieldObjectDestroyed();
+
+ /*
+ Things that could be added:
+
+ 1. Test virtual functions that are called, signals that are
+ emitted, etc.
+
+ 2. Test QWizardPage more thorougly.
+
+ 3. Test the look and field a bit more (especially the
+ different wizard styles, and how they interact with
+ pixmaps, titles, subtitles, etc.).
+
+ 4. Test minimum sizes, sizes, maximum sizes, resizing, etc.
+
+ 5. Try setting various options and wizard styles in various
+ orders and check that the results are the same every time,
+ no matter the order in which the properties were set.
+
+ -> Initial version done (tst_QWizard::combinations())
+
+ 6. Test done() and restart().
+
+ 7. Test default properties of built-in widgets.
+
+ 8. Test mutual exclusiveness of Next and Commit buttons.
+ */
+};
+
+tst_QWizard::tst_QWizard()
+{
+}
+
+void tst_QWizard::init()
+{
+#ifdef Q_OS_WINCE //disable magic for WindowsCE
+ qApp->setAutoMaximizeThreshold(-1);
+#endif
+}
+
+void tst_QWizard::cleanup()
+{
+}
+
+void tst_QWizard::buttonText()
+{
+ QWizard wizard;
+ wizard.setWizardStyle(QWizard::ClassicStyle);
+
+ // Check the buttons' original text in Classic and Modern styles.
+ for (int pass = 0; pass < 2; ++pass) {
+ QCOMPARE(wizard.buttonText(QWizard::BackButton), QString("< &Back"));
+ QVERIFY(wizard.buttonText(QWizard::NextButton).contains("Next"));
+ QVERIFY(wizard.buttonText(QWizard::FinishButton).endsWith("Finish"));
+ QVERIFY(wizard.buttonText(QWizard::CancelButton).endsWith("Cancel"));
+ QVERIFY(wizard.buttonText(QWizard::HelpButton).endsWith("Help"));
+
+ QVERIFY(wizard.buttonText(QWizard::CustomButton1).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::CustomButton2).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::CustomButton3).isEmpty());
+
+ // robustness
+ QVERIFY(wizard.buttonText(QWizard::Stretch).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::NoButton).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::NStandardButtons).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::NButtons).isEmpty());
+
+ wizard.setWizardStyle(QWizard::ModernStyle);
+ }
+
+ // Check the buttons' original text in Mac style.
+ wizard.setWizardStyle(QWizard::MacStyle);
+
+ QCOMPARE(wizard.buttonText(QWizard::BackButton), QString("Go Back"));
+ QCOMPARE(wizard.buttonText(QWizard::NextButton), QString("Continue"));
+ QCOMPARE(wizard.buttonText(QWizard::FinishButton), QString("Done"));
+ QCOMPARE(wizard.buttonText(QWizard::CancelButton), QString("Cancel"));
+ QCOMPARE(wizard.buttonText(QWizard::HelpButton), QString("Help"));
+
+ QVERIFY(wizard.buttonText(QWizard::CustomButton1).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::CustomButton2).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::CustomButton3).isEmpty());
+
+ // robustness
+ QVERIFY(wizard.buttonText(QWizard::Stretch).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::NoButton).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::NStandardButtons).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::NButtons).isEmpty());
+
+ // Modify the buttons' text and see what happens.
+ wizard.setButtonText(QWizard::NextButton, "N&este");
+ wizard.setButtonText(QWizard::CustomButton2, "&Cucu");
+ wizard.setButtonText(QWizard::Stretch, "Stretch");
+
+ QCOMPARE(wizard.buttonText(QWizard::BackButton), QString("Go Back"));
+ QCOMPARE(wizard.buttonText(QWizard::NextButton), QString("N&este"));
+ QCOMPARE(wizard.buttonText(QWizard::FinishButton), QString("Done"));
+ QCOMPARE(wizard.buttonText(QWizard::CancelButton), QString("Cancel"));
+ QCOMPARE(wizard.buttonText(QWizard::HelpButton), QString("Help"));
+
+ QVERIFY(wizard.buttonText(QWizard::CustomButton1).isEmpty());
+ QCOMPARE(wizard.buttonText(QWizard::CustomButton2), QString("&Cucu"));
+ QVERIFY(wizard.buttonText(QWizard::CustomButton3).isEmpty());
+
+ // robustness
+ QVERIFY(wizard.buttonText(QWizard::Stretch).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::NoButton).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::NStandardButtons).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::NButtons).isEmpty());
+
+ // Switch back to Classic style and see what happens.
+ wizard.setWizardStyle(QWizard::ClassicStyle);
+
+ for (int pass = 0; pass < 2; ++pass) {
+ QCOMPARE(wizard.buttonText(QWizard::BackButton), QString("< &Back"));
+ QCOMPARE(wizard.buttonText(QWizard::NextButton), QString("N&este"));
+ QVERIFY(wizard.buttonText(QWizard::FinishButton).endsWith("Finish"));
+ QVERIFY(wizard.buttonText(QWizard::CancelButton).endsWith("Cancel"));
+ QVERIFY(wizard.buttonText(QWizard::HelpButton).endsWith("Help"));
+
+ QVERIFY(wizard.buttonText(QWizard::CustomButton1).isEmpty());
+ QCOMPARE(wizard.buttonText(QWizard::CustomButton2), QString("&Cucu"));
+ QVERIFY(wizard.buttonText(QWizard::CustomButton3).isEmpty());
+
+ // robustness
+ QVERIFY(wizard.buttonText(QWizard::Stretch).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::NoButton).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::NStandardButtons).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::NButtons).isEmpty());
+
+ wizard.setOptions(QWizard::NoDefaultButton
+ | QWizard::NoBackButtonOnStartPage
+ | QWizard::NoBackButtonOnLastPage
+ | QWizard::DisabledBackButtonOnLastPage
+ | QWizard::NoCancelButton
+ | QWizard::CancelButtonOnLeft
+ | QWizard::HaveHelpButton
+ | QWizard::HelpButtonOnRight
+ | QWizard::HaveCustomButton1
+ | QWizard::HaveCustomButton2
+ | QWizard::HaveCustomButton3);
+ }
+}
+
+void tst_QWizard::setButtonLayout()
+{
+ QList<QWizard::WizardButton> layout;
+
+ QWizard wizard;
+ wizard.setWizardStyle(QWizard::ClassicStyle);
+ wizard.setOptions(0);
+ wizard.setButtonLayout(layout);
+ wizard.show();
+ qApp->processEvents();
+
+ // if these crash, this means there's a bug in QWizard
+ QVERIFY(wizard.button(QWizard::NextButton)->text().contains("Next"));
+ QVERIFY(wizard.button(QWizard::BackButton)->text().contains("Back"));
+ QVERIFY(wizard.button(QWizard::FinishButton)->text().contains("Finish"));
+ QVERIFY(wizard.button(QWizard::CancelButton)->text().contains("Cancel"));
+ QVERIFY(wizard.button(QWizard::HelpButton)->text().contains("Help"));
+ QVERIFY(wizard.button(QWizard::CustomButton1)->text().isEmpty());
+ QVERIFY(wizard.button(QWizard::CustomButton2)->text().isEmpty());
+ QVERIFY(wizard.button(QWizard::CustomButton3)->text().isEmpty());
+ QVERIFY(!wizard.button(QWizard::Stretch));
+ QVERIFY(!wizard.button(QWizard::NoButton));
+
+ QVERIFY(!wizard.button(QWizard::NextButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::HelpButton)->isVisible());
+
+ layout << QWizard::NextButton << QWizard::HelpButton;
+ wizard.setButtonLayout(layout);
+ qApp->processEvents();
+
+ QVERIFY(!wizard.button(QWizard::NextButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+ QVERIFY(wizard.button(QWizard::HelpButton)->isVisible());
+
+ wizard.addPage(new QWizardPage);
+ wizard.addPage(new QWizardPage);
+ qApp->processEvents();
+
+ QVERIFY(!wizard.button(QWizard::NextButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+ QVERIFY(wizard.button(QWizard::HelpButton)->isVisible());
+
+ wizard.restart();
+ qApp->processEvents();
+
+ QVERIFY(wizard.button(QWizard::NextButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+ QVERIFY(wizard.button(QWizard::HelpButton)->isVisible());
+
+ layout.clear();
+ layout << QWizard::NextButton << QWizard::HelpButton << QWizard::BackButton
+ << QWizard::FinishButton << QWizard::CancelButton << QWizard::Stretch
+ << QWizard::CustomButton2;
+
+ // Turn on all the button-related wizard options. Some of these
+ // should have no impact on a custom layout; others should.
+ wizard.setButtonLayout(layout);
+ wizard.setOptions(QWizard::NoDefaultButton
+ | QWizard::NoBackButtonOnStartPage
+ | QWizard::NoBackButtonOnLastPage
+ | QWizard::DisabledBackButtonOnLastPage
+ | QWizard::HaveNextButtonOnLastPage
+ | QWizard::HaveFinishButtonOnEarlyPages
+ | QWizard::NoCancelButton
+ | QWizard::CancelButtonOnLeft
+ | QWizard::HaveHelpButton
+ | QWizard::HelpButtonOnRight
+ | QWizard::HaveCustomButton1
+ | QWizard::HaveCustomButton2
+ | QWizard::HaveCustomButton3);
+ qApp->processEvents();
+
+ // we're on first page
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+ QVERIFY(wizard.button(QWizard::FinishButton)->isVisible());
+ QVERIFY(wizard.button(QWizard::CancelButton)->isVisible()); // NoCancelButton overridden
+ QVERIFY(wizard.button(QWizard::HelpButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::CustomButton1)->isVisible());
+ QVERIFY(wizard.button(QWizard::CustomButton2)->isVisible()); // HaveCustomButton2 overridden
+ QVERIFY(!wizard.button(QWizard::CustomButton3)->isVisible());
+
+ wizard.next();
+ qApp->processEvents();
+
+ // we're on last page
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+ QVERIFY(wizard.button(QWizard::NextButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::NextButton)->isEnabled());
+ QVERIFY(wizard.button(QWizard::FinishButton)->isVisible());
+ QVERIFY(wizard.button(QWizard::FinishButton)->isEnabled());
+ QVERIFY(wizard.button(QWizard::CancelButton)->isVisible()); // NoCancelButton overridden
+ QVERIFY(wizard.button(QWizard::HelpButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::CustomButton1)->isVisible());
+ QVERIFY(wizard.button(QWizard::CustomButton2)->isVisible()); // HaveCustomButton2 overridden
+ QVERIFY(!wizard.button(QWizard::CustomButton3)->isVisible());
+
+ // Check that the buttons are in the right order on screen.
+ for (int pass = 0; pass < 2; ++pass) {
+ wizard.setLayoutDirection(pass == 0 ? Qt::LeftToRight : Qt::RightToLeft);
+ qApp->processEvents();
+
+ int sign = (pass == 0) ? +1 : -1;
+
+ int p[5];
+ p[0] = sign * wizard.button(QWizard::NextButton)->x();
+ p[1] = sign * wizard.button(QWizard::HelpButton)->x();
+ p[2] = sign * wizard.button(QWizard::FinishButton)->x();
+ p[3] = sign * wizard.button(QWizard::CancelButton)->x();
+ p[4] = sign * wizard.button(QWizard::CustomButton2)->x();
+
+ QVERIFY(p[0] < p[1]);
+ QVERIFY(p[1] < p[2]);
+ QVERIFY(p[2] < p[3]);
+ QVERIFY(p[3] < p[4]);
+ }
+
+ layout.clear();
+ wizard.setButtonLayout(layout);
+ qApp->processEvents();
+
+ for (int i = -1; i < 50; ++i) {
+ QAbstractButton *button = wizard.button(QWizard::WizardButton(i));
+ QVERIFY(!button || !button->isVisible());
+ }
+}
+
+void tst_QWizard::setButton()
+{
+ QPointer<QToolButton> toolButton = new QToolButton;
+
+ QWizard wizard;
+ wizard.setWizardStyle(QWizard::ClassicStyle);
+ wizard.setButton(QWizard::NextButton, toolButton);
+ wizard.setButton(QWizard::CustomButton2, new QCheckBox("Kustom 2"));
+
+ QVERIFY(qobject_cast<QToolButton *>(wizard.button(QWizard::NextButton)));
+ QVERIFY(qobject_cast<QCheckBox *>(wizard.button(QWizard::CustomButton2)));
+ QVERIFY(qobject_cast<QPushButton *>(wizard.button(QWizard::CustomButton1)));
+
+ QVERIFY(toolButton != 0);
+
+ // resetting the same button does nothing
+ wizard.setButton(QWizard::NextButton, toolButton);
+ QVERIFY(toolButton != 0);
+
+ // revert to default button
+ wizard.setButton(QWizard::NextButton, 0);
+ QVERIFY(toolButton == 0);
+ QVERIFY(qobject_cast<QPushButton *>(wizard.button(QWizard::NextButton)));
+ QVERIFY(wizard.button(QWizard::NextButton)->text().contains("Next"));
+}
+
+void tst_QWizard::setTitleFormatEtc()
+{
+ QWizard wizard;
+ QVERIFY(wizard.titleFormat() == Qt::AutoText);
+ QVERIFY(wizard.subTitleFormat() == Qt::AutoText);
+
+ wizard.setTitleFormat(Qt::RichText);
+ QVERIFY(wizard.titleFormat() == Qt::RichText);
+ QVERIFY(wizard.subTitleFormat() == Qt::AutoText);
+
+ wizard.setSubTitleFormat(Qt::PlainText);
+ QVERIFY(wizard.titleFormat() == Qt::RichText);
+ QVERIFY(wizard.subTitleFormat() == Qt::PlainText);
+}
+
+void tst_QWizard::setPixmap()
+{
+ QPixmap p1(1, 1);
+ QPixmap p2(2, 2);
+ QPixmap p3(3, 3);
+ QPixmap p4(4, 4);
+ QPixmap p5(5, 5);
+
+ QWizard wizard;
+ QWizardPage *page = new QWizardPage;
+ QWizardPage *page2 = new QWizardPage;
+
+ wizard.addPage(page);
+ wizard.addPage(page2);
+
+ QVERIFY(wizard.pixmap(QWizard::BannerPixmap).isNull());
+ QVERIFY(wizard.pixmap(QWizard::LogoPixmap).isNull());
+ QVERIFY(wizard.pixmap(QWizard::WatermarkPixmap).isNull());
+#ifdef Q_WS_MAC
+ if (QSysInfo::MacintoshVersion > QSysInfo::MV_10_3)
+ QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull() == false);
+ else // fall through since the image doesn't exist on a 10.3 system.
+ QVERIFY(page->pixmap(QWizard::BackgroundPixmap).isNull());
+#else
+ QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull());
+#endif
+
+ QVERIFY(page->pixmap(QWizard::BannerPixmap).isNull());
+ QVERIFY(page->pixmap(QWizard::LogoPixmap).isNull());
+ QVERIFY(page->pixmap(QWizard::WatermarkPixmap).isNull());
+#ifdef Q_WS_MAC
+ if (QSysInfo::MacintoshVersion > QSysInfo::MV_10_3)
+ QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull() == false);
+ else // fall through since the image doesn't exist on a 10.3 system.
+ QVERIFY(page->pixmap(QWizard::BackgroundPixmap).isNull());
+#else
+ QVERIFY(page->pixmap(QWizard::BackgroundPixmap).isNull());
+#endif
+ wizard.setPixmap(QWizard::BannerPixmap, p1);
+ wizard.setPixmap(QWizard::LogoPixmap, p2);
+ wizard.setPixmap(QWizard::WatermarkPixmap, p3);
+ wizard.setPixmap(QWizard::BackgroundPixmap, p4);
+
+ page->setPixmap(QWizard::LogoPixmap, p5);
+
+ QVERIFY(wizard.pixmap(QWizard::BannerPixmap).size() == p1.size());
+ QVERIFY(wizard.pixmap(QWizard::LogoPixmap).size() == p2.size());
+ QVERIFY(wizard.pixmap(QWizard::WatermarkPixmap).size() == p3.size());
+ QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).size() == p4.size());
+
+ QVERIFY(page->pixmap(QWizard::BannerPixmap).size() == p1.size());
+ QVERIFY(page->pixmap(QWizard::LogoPixmap).size() == p5.size());
+ QVERIFY(page->pixmap(QWizard::WatermarkPixmap).size() == p3.size());
+ QVERIFY(page->pixmap(QWizard::BackgroundPixmap).size() == p4.size());
+
+ QVERIFY(page2->pixmap(QWizard::BannerPixmap).size() == p1.size());
+ QVERIFY(page2->pixmap(QWizard::LogoPixmap).size() == p2.size());
+ QVERIFY(page2->pixmap(QWizard::WatermarkPixmap).size() == p3.size());
+ QVERIFY(page2->pixmap(QWizard::BackgroundPixmap).size() == p4.size());
+}
+
+class MyPage1 : public QWizardPage
+{
+public:
+ MyPage1() {
+ edit1 = new QLineEdit("Bla 1", this);
+
+ edit2 = new QLineEdit("Bla 2", this);
+ edit2->setInputMask("Mask");
+
+ edit3 = new QLineEdit("Bla 3", this);
+ edit3->setMaxLength(25);
+
+ edit4 = new QLineEdit("Bla 4", this);
+ }
+
+ void registerField(const QString &name, QWidget *widget,
+ const char *property = 0,
+ const char *changedSignal = 0)
+ { QWizardPage::registerField(name, widget, property, changedSignal); }
+
+ QLineEdit *edit1;
+ QLineEdit *edit2;
+ QLineEdit *edit3;
+ QLineEdit *edit4;
+};
+
+void tst_QWizard::setDefaultProperty()
+{
+ QWizard wizard;
+ MyPage1 *page = new MyPage1;
+ wizard.addPage(page);
+
+ page->registerField("edit1", page->edit1);
+
+ wizard.setDefaultProperty("QLineEdit", "inputMask", 0);
+ page->registerField("edit2", page->edit2);
+
+ wizard.setDefaultProperty("QLineEdit", "maxLength", 0);
+ page->registerField("edit3", page->edit3);
+
+ wizard.setDefaultProperty("QLineEdit", "text", SIGNAL(textChanged(QString)));
+ page->registerField("edit3bis", page->edit3);
+
+ wizard.setDefaultProperty("QWidget", "enabled", 0); // less specific, i.e. ignored
+ page->registerField("edit4", page->edit4);
+ QTest::ignoreMessage(QtWarningMsg,"QWizard::setField: Couldn't write to property 'customProperty'");
+ wizard.setDefaultProperty("QLineEdit", "customProperty", 0);
+ page->registerField("edit4bis", page->edit4);
+
+ QCOMPARE(wizard.field("edit1").toString(), QString("Bla 1"));
+ QCOMPARE(wizard.field("edit2").toString(), page->edit2->inputMask());
+ QCOMPARE(wizard.field("edit3").toInt(), 25);
+ QCOMPARE(wizard.field("edit3bis").toString(), QString("Bla 3"));
+ QCOMPARE(wizard.field("edit4").toString(), QString("Bla 4"));
+ QCOMPARE(wizard.field("edit4bis").toString(), QString());
+
+ wizard.setField("edit1", "Alpha");
+ wizard.setField("edit2", "Beta");
+ wizard.setField("edit3", 50);
+ wizard.setField("edit3bis", "Gamma");
+ wizard.setField("edit4", "Delta");
+ wizard.setField("edit4bis", "Epsilon");
+
+ QCOMPARE(wizard.field("edit1").toString(), QString("Alpha"));
+ QVERIFY(wizard.field("edit2").toString().contains("Beta"));
+ QCOMPARE(wizard.field("edit3").toInt(), 50);
+ QCOMPARE(wizard.field("edit3bis").toString(), QString("Gamma"));
+ QCOMPARE(wizard.field("edit4").toString(), QString("Delta"));
+ QCOMPARE(wizard.field("edit4bis").toString(), QString("Epsilon"));
+
+ // make sure the data structure is reasonable
+ for (int i = 0; i < 200000; ++i) {
+ wizard.setDefaultProperty("QLineEdit", "x" + QByteArray::number(i), 0);
+ wizard.setDefaultProperty("QLabel", "y" + QByteArray::number(i), 0);
+ }
+}
+
+void tst_QWizard::addPage()
+{
+ QWidget *parent = new QWidget;
+ QWizard wizard;
+ const int N = 100;
+ QWizardPage *pages[N];
+ QSignalSpy spy(&wizard, SIGNAL(pageAdded(int)));
+
+ for (int i = 0; i < N; ++i) {
+ pages[i] = new QWizardPage(parent);
+ QCOMPARE(wizard.addPage(pages[i]), i);
+ QCOMPARE(pages[i]->window(), (QWidget *)&wizard);
+ QCOMPARE(wizard.startId(), 0);
+ QCOMPARE(spy.count(), 1);
+ QList<QVariant> arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), i);
+ }
+
+ for (int i = 0; i < N; ++i) {
+ QVERIFY(pages[i] == wizard.page(i));
+ }
+ QVERIFY(!wizard.page(-1));
+ QVERIFY(!wizard.page(N));
+ QVERIFY(!wizard.page(N + 1));
+
+ wizard.setPage(N + 50, new QWizardPage);
+ QCOMPARE(spy.count(), 1);
+ QList<QVariant> arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), N + 50);
+ wizard.setPage(-3000, new QWizardPage);
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), -3000);
+
+ QWizardPage *pageX = new QWizardPage;
+ QCOMPARE(wizard.addPage(pageX), N + 51);
+ QCOMPARE(wizard.page(N + 51), pageX);
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), N + 51);
+
+ QCOMPARE(wizard.addPage(new QWizardPage), N + 52);
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), N + 52);
+
+ QTest::ignoreMessage(QtWarningMsg,"QWizard::setPage: Cannot insert null page");
+ wizard.addPage(0); // generates a warning
+ QCOMPARE(spy.count(), 0);
+ delete parent;
+}
+
+#define CHECK_VISITED(wizard, list) \
+ do { \
+ QList<int> myList = list; \
+ QCOMPARE((wizard).visitedPages(), myList); \
+ Q_FOREACH(int id, myList) \
+ QVERIFY((wizard).hasVisitedPage(id)); \
+ } while (0)
+
+void tst_QWizard::setPage()
+{
+ QWidget *parent = new QWidget;
+ QWizard wizard;
+ QWizardPage *page;
+ QSignalSpy spy(&wizard, SIGNAL(pageAdded(int)));
+
+ QCOMPARE(wizard.startId(), -1);
+ QCOMPARE(wizard.currentId(), -1);
+ QVERIFY(!wizard.currentPage());
+ QCOMPARE(wizard.nextId(), -1);
+
+ page = new QWizardPage(parent);
+ QTest::ignoreMessage(QtWarningMsg,"QWizard::setPage: Cannot insert page with ID -1");
+ wizard.setPage(-1, page); // gives a warning and does nothing
+ QCOMPARE(spy.count(), 0);
+ QVERIFY(!wizard.page(-2));
+ QVERIFY(!wizard.page(-1));
+ QVERIFY(!wizard.page(0));
+ QCOMPARE(wizard.startId(), -1);
+ QCOMPARE(wizard.currentId(), -1);
+ QVERIFY(!wizard.currentPage());
+ QCOMPARE(wizard.nextId(), -1);
+ CHECK_VISITED(wizard, QList<int>());
+
+ page = new QWizardPage(parent);
+ wizard.setPage(0, page);
+ QCOMPARE(spy.count(), 1);
+ QList<QVariant> arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), 0);
+ QCOMPARE(page->window(), (QWidget *)&wizard);
+ QCOMPARE(wizard.page(0), page);
+ QCOMPARE(wizard.startId(), 0);
+ QCOMPARE(wizard.currentId(), -1);
+ QVERIFY(!wizard.currentPage());
+ QCOMPARE(wizard.nextId(), -1);
+ CHECK_VISITED(wizard, QList<int>());
+
+ page = new QWizardPage(parent);
+ wizard.setPage(-2, page);
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), -2);
+ QCOMPARE(page->window(), (QWidget *)&wizard);
+ QCOMPARE(wizard.page(-2), page);
+ QCOMPARE(wizard.startId(), -2);
+ QCOMPARE(wizard.currentId(), -1);
+ QVERIFY(!wizard.currentPage());
+ QCOMPARE(wizard.nextId(), -1);
+ CHECK_VISITED(wizard, QList<int>());
+
+ wizard.restart();
+ QCOMPARE(wizard.page(-2), page);
+ QCOMPARE(wizard.startId(), -2);
+ QCOMPARE(wizard.currentId(), -2);
+ QVERIFY(wizard.currentPage() == page);
+ QCOMPARE(wizard.nextId(), 0);
+ CHECK_VISITED(wizard, QList<int>() << -2);
+
+ page = new QWizardPage(parent);
+ wizard.setPage(2, page);
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), 2);
+ QCOMPARE(wizard.page(2), page);
+ QCOMPARE(wizard.startId(), -2);
+ QCOMPARE(wizard.currentId(), -2);
+ QVERIFY(wizard.currentPage() == wizard.page(-2));
+ QCOMPARE(wizard.nextId(), 0);
+ CHECK_VISITED(wizard, QList<int>() << -2);
+
+ wizard.restart();
+ QCOMPARE(wizard.startId(), -2);
+ QCOMPARE(wizard.currentId(), -2);
+ QVERIFY(wizard.currentPage() == wizard.page(-2));
+ QCOMPARE(wizard.nextId(), 0);
+ CHECK_VISITED(wizard, QList<int>() << -2);
+
+ page = new QWizardPage(parent);
+ wizard.setPage(-3, page);
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), -3);
+ QCOMPARE(wizard.page(-3), page);
+ QCOMPARE(wizard.startId(), -3);
+ QCOMPARE(wizard.currentId(), -2);
+ QVERIFY(wizard.currentPage() == wizard.page(-2));
+ QCOMPARE(wizard.nextId(), 0);
+ CHECK_VISITED(wizard, QList<int>() << -2);
+
+ wizard.restart();
+ QCOMPARE(wizard.startId(), -3);
+ QCOMPARE(wizard.currentId(), -3);
+ QVERIFY(wizard.currentPage() == wizard.page(-3));
+ QCOMPARE(wizard.nextId(), -2);
+ CHECK_VISITED(wizard, QList<int>() << -3);
+
+ wizard.next();
+ QCOMPARE(wizard.startId(), -3);
+ QCOMPARE(wizard.currentId(), -2);
+ QVERIFY(wizard.currentPage() == wizard.page(-2));
+ QCOMPARE(wizard.nextId(), 0);
+ CHECK_VISITED(wizard, QList<int>() << -3 << -2);
+
+ wizard.next();
+ QCOMPARE(wizard.startId(), -3);
+ QCOMPARE(wizard.currentId(), 0);
+ QVERIFY(wizard.currentPage() == wizard.page(0));
+ QCOMPARE(wizard.nextId(), 2);
+ CHECK_VISITED(wizard, QList<int>() << -3 << -2 << 0);
+
+ for (int i = 0; i < 100; ++i) {
+ wizard.next();
+ QCOMPARE(wizard.startId(), -3);
+ QCOMPARE(wizard.currentId(), 2);
+ QVERIFY(wizard.currentPage() == wizard.page(2));
+ QCOMPARE(wizard.nextId(), -1);
+ CHECK_VISITED(wizard, QList<int>() << -3 << -2 << 0 << 2);
+ }
+
+ wizard.back();
+ QCOMPARE(wizard.startId(), -3);
+ QCOMPARE(wizard.currentId(), 0);
+ QVERIFY(wizard.currentPage() == wizard.page(0));
+ QCOMPARE(wizard.nextId(), 2);
+ CHECK_VISITED(wizard, QList<int>() << -3 << -2 << 0);
+
+ wizard.back();
+ QCOMPARE(wizard.startId(), -3);
+ QCOMPARE(wizard.currentId(), -2);
+ QVERIFY(wizard.currentPage() == wizard.page(-2));
+ QCOMPARE(wizard.nextId(), 0);
+ CHECK_VISITED(wizard, QList<int>() << -3 << -2);
+
+ for (int i = 0; i < 100; ++i) {
+ wizard.back();
+ QCOMPARE(wizard.startId(), -3);
+ QCOMPARE(wizard.currentId(), -3);
+ QVERIFY(wizard.currentPage() == wizard.page(-3));
+ QCOMPARE(wizard.nextId(), -2);
+ CHECK_VISITED(wizard, QList<int>() << -3);
+ }
+
+ for (int i = 0; i < 100; ++i) {
+ wizard.restart();
+ QCOMPARE(wizard.startId(), -3);
+ QCOMPARE(wizard.currentId(), -3);
+ QVERIFY(wizard.currentPage() == wizard.page(-3));
+ QCOMPARE(wizard.nextId(), -2);
+ CHECK_VISITED(wizard, QList<int>() << -3);
+ }
+ QCOMPARE(spy.count(), 0);
+ delete parent;
+}
+
+void tst_QWizard::setStartId()
+{
+ QWizard wizard;
+ QCOMPARE(wizard.startId(), -1);
+
+ wizard.setPage(INT_MIN, new QWizardPage);
+ QCOMPARE(wizard.startId(), INT_MIN);
+
+ wizard.setPage(-2, new QWizardPage);
+ QCOMPARE(wizard.startId(), INT_MIN);
+
+ wizard.setPage(0, new QWizardPage);
+ QCOMPARE(wizard.startId(), INT_MIN);
+
+ wizard.setPage(1, new QWizardPage);
+ QCOMPARE(wizard.startId(), INT_MIN);
+
+ wizard.setPage(INT_MAX, new QWizardPage);
+ QCOMPARE(wizard.startId(), INT_MIN);
+
+ QTest::ignoreMessage(QtWarningMsg,"QWizard::setStartId: Invalid page ID 123");
+ wizard.setStartId(123);
+ QCOMPARE(wizard.startId(), INT_MIN);
+
+ wizard.setStartId(-1);
+ QCOMPARE(wizard.startId(), INT_MIN);
+
+ wizard.setStartId(-2);
+ QCOMPARE(wizard.startId(), -2);
+ QCOMPARE(wizard.nextId(), -1);
+
+ wizard.setStartId(-1);
+ QCOMPARE(wizard.startId(), INT_MIN);
+
+ wizard.setStartId(-2);
+ QCOMPARE(wizard.startId(), -2);
+ QCOMPARE(wizard.nextId(), -1);
+
+ wizard.restart();
+ QCOMPARE(wizard.startId(), -2);
+ QCOMPARE(wizard.currentId(), -2);
+ QVERIFY(wizard.currentPage() == wizard.page(-2));
+ QCOMPARE(wizard.nextId(), 0);
+
+ wizard.next();
+ QCOMPARE(wizard.startId(), -2);
+ QCOMPARE(wizard.currentId(), 0);
+ QVERIFY(wizard.currentPage() == wizard.page(0));
+ QCOMPARE(wizard.nextId(), 1);
+
+ wizard.setStartId(INT_MIN);
+ QCOMPARE(wizard.startId(), INT_MIN);
+ QCOMPARE(wizard.currentId(), 0);
+ QVERIFY(wizard.currentPage() == wizard.page(0));
+ QCOMPARE(wizard.nextId(), 1);
+
+ wizard.next();
+ QCOMPARE(wizard.startId(), INT_MIN);
+ QCOMPARE(wizard.currentId(), 1);
+ QVERIFY(wizard.currentPage() == wizard.page(1));
+ QCOMPARE(wizard.nextId(), INT_MAX);
+
+ wizard.next();
+ QCOMPARE(wizard.startId(), INT_MIN);
+ QCOMPARE(wizard.currentId(), INT_MAX);
+ QVERIFY(wizard.currentPage() == wizard.page(INT_MAX));
+ QCOMPARE(wizard.nextId(), -1);
+ CHECK_VISITED(wizard, QList<int>() << -2 << 0 << 1 << INT_MAX);
+}
+
+struct MyPage2 : public QWizardPage
+{
+public:
+ MyPage2() : init(0), cleanup(0), validate(0) {}
+
+ void initializePage() { ++init; QWizardPage::initializePage(); }
+ void cleanupPage() { ++cleanup; QWizardPage::cleanupPage(); }
+ bool validatePage() { ++validate; return QWizardPage::validatePage(); }
+
+ bool check(int init, int cleanup)
+ {
+ return init == this->init
+ && cleanup == this->cleanup
+ && (this->init == this->cleanup || this->init - 1 == this->cleanup);
+ }
+
+ int init;
+ int cleanup;
+ int validate;
+};
+
+#define CHECK_PAGE_INIT(i0, c0, i1, c1, i2, c2) \
+ QVERIFY(page0->check((i0), (c0))); \
+ QVERIFY(page1->check((i1), (c1))); \
+ QVERIFY(page2->check((i2), (c2)));
+
+void tst_QWizard::setOption_IndependentPages()
+{
+ MyPage2 *page0 = new MyPage2;
+ MyPage2 *page1 = new MyPage2;
+ MyPage2 *page2 = new MyPage2;
+
+ QWizard wizard;
+ wizard.addPage(page0);
+ wizard.addPage(page1);
+ wizard.addPage(page2);
+
+ QVERIFY(!wizard.testOption(QWizard::IndependentPages));
+
+ wizard.restart();
+
+ // Make sure initializePage() and cleanupPage() are called are
+ // they should when the
+ // wizard.testOption(QWizard::IndependentPages option is off.
+ for (int i = 0; i < 10; ++i) {
+ CHECK_PAGE_INIT(i + 1, i, i, i, i, i);
+
+ wizard.next();
+ CHECK_PAGE_INIT(i + 1, i, i + 1, i, i, i);
+
+ wizard.next();
+ CHECK_PAGE_INIT(i + 1, i, i + 1, i, i + 1, i);
+
+ wizard.next();
+ CHECK_PAGE_INIT(i + 1, i, i + 1, i, i + 1, i);
+
+ wizard.back();
+ CHECK_PAGE_INIT(i + 1, i, i + 1, i, i + 1, i + 1);
+
+ wizard.back();
+ CHECK_PAGE_INIT(i + 1, i, i + 1, i + 1, i + 1, i + 1);
+
+ wizard.back();
+ CHECK_PAGE_INIT(i + 1, i, i + 1, i + 1, i + 1, i + 1);
+
+ wizard.restart();
+ }
+
+ CHECK_PAGE_INIT(11, 10, 10, 10, 10, 10);
+
+ wizard.next();
+ CHECK_PAGE_INIT(11, 10, 11, 10, 10, 10);
+
+ // Now, turn on the option and check that they're called at the
+ // appropriate times (which aren't the same).
+ wizard.setOption(QWizard::IndependentPages, true);
+ CHECK_PAGE_INIT(11, 10, 11, 10, 10, 10);
+
+ wizard.back();
+ CHECK_PAGE_INIT(11, 10, 11, 10, 10, 10);
+
+ wizard.next();
+ CHECK_PAGE_INIT(11, 10, 11, 10, 10, 10);
+
+ wizard.next();
+ CHECK_PAGE_INIT(11, 10, 11, 10, 11, 10);
+
+ wizard.next();
+ CHECK_PAGE_INIT(11, 10, 11, 10, 11, 10);
+
+ wizard.back();
+ CHECK_PAGE_INIT(11, 10, 11, 10, 11, 10);
+
+ wizard.setStartId(2);
+
+ wizard.restart();
+ CHECK_PAGE_INIT(11, 11, 11, 11, 12, 11);
+
+ wizard.back();
+ CHECK_PAGE_INIT(11, 11, 11, 11, 12, 11);
+
+ wizard.next();
+ CHECK_PAGE_INIT(11, 11, 11, 11, 12, 11);
+
+ wizard.setStartId(0);
+ wizard.restart();
+ CHECK_PAGE_INIT(12, 11, 11, 11, 12, 12);
+
+ wizard.next();
+ CHECK_PAGE_INIT(12, 11, 12, 11, 12, 12);
+
+ wizard.next();
+ CHECK_PAGE_INIT(12, 11, 12, 11, 13, 12);
+
+ wizard.back();
+ CHECK_PAGE_INIT(12, 11, 12, 11, 13, 12);
+
+ // Fun stuff here.
+
+ wizard.setOption(QWizard::IndependentPages, false);
+ CHECK_PAGE_INIT(12, 11, 12, 11, 13, 13);
+
+ wizard.setOption(QWizard::IndependentPages, true);
+ CHECK_PAGE_INIT(12, 11, 12, 11, 13, 13);
+
+ wizard.setOption(QWizard::IndependentPages, false);
+ CHECK_PAGE_INIT(12, 11, 12, 11, 13, 13);
+
+ wizard.back();
+ CHECK_PAGE_INIT(12, 11, 12, 12, 13, 13);
+
+ wizard.back();
+ CHECK_PAGE_INIT(12, 11, 12, 12, 13, 13);
+}
+
+void tst_QWizard::setOption_IgnoreSubTitles()
+{
+#if defined(Q_OS_WINCE)
+ QSKIP("Skipped because of limited resources and potential crash. (Task: 166824)", SkipAll);
+#endif
+ QWizard wizard1;
+ wizard1.setButtonLayout(QList<QWizard::WizardButton>() << QWizard::CancelButton);
+ wizard1.resize(500, 500);
+ QVERIFY(!wizard1.testOption(QWizard::IgnoreSubTitles));
+ QWizardPage *page11 = new QWizardPage;
+ page11->setTitle("Page X");
+ page11->setSubTitle("Some subtitle");
+
+ QWizardPage *page12 = new QWizardPage;
+ page12->setTitle("Page X");
+
+ wizard1.addPage(page11);
+ wizard1.addPage(page12);
+
+ QWizard wizard2;
+ wizard2.setButtonLayout(QList<QWizard::WizardButton>() << QWizard::CancelButton);
+ wizard2.resize(500, 500);
+ wizard2.setOption(QWizard::IgnoreSubTitles, true);
+ QWizardPage *page21 = new QWizardPage;
+ page21->setTitle("Page X");
+ page21->setSubTitle("Some subtitle");
+
+ QWizardPage *page22 = new QWizardPage;
+ page22->setTitle("Page X");
+
+ wizard2.addPage(page21);
+ wizard2.addPage(page22);
+
+ wizard1.show();
+ wizard2.show();
+
+ // Check that subtitles are shown when they should (i.e.,
+ // they're set and IgnoreSubTitles is off).
+
+ qApp->setActiveWindow(0); // ensure no focus rectangle around cancel button
+ QImage i11 = grabWidget(&wizard1);
+ QImage i21 = grabWidget(&wizard2);
+ QVERIFY(i11 != i21);
+
+ wizard1.next();
+ wizard2.next();
+
+ QImage i12 = grabWidget(&wizard1);
+ QImage i22 = grabWidget(&wizard2);
+ QVERIFY(i12 == i22);
+ QVERIFY(i21 == i22);
+
+ wizard1.back();
+ wizard2.back();
+
+ QImage i13 = grabWidget(&wizard1);
+ QImage i23 = grabWidget(&wizard2);
+ QVERIFY(i13 == i11);
+ QVERIFY(i23 == i21);
+
+ wizard1.setOption(QWizard::IgnoreSubTitles, true);
+ wizard2.setOption(QWizard::IgnoreSubTitles, false);
+
+ QImage i14 = grabWidget(&wizard1);
+ QImage i24 = grabWidget(&wizard2);
+ QVERIFY(i14 == i21);
+ QVERIFY(i24 == i11);
+
+ // Check the impact of subtitles on the rest of the layout, by
+ // using a subtitle that looks empty (but that isn't). In
+ // Classic and Modern styles, this should be enough to trigger a
+ // "header"; in Mac style, this only creates a QLabel, with no
+ // text, i.e. it doesn't affect the layout.
+
+ page11->setSubTitle("<b></b>"); // not quite empty, but looks empty
+
+ for (int i = 0; i < 3; ++i) {
+ for (int j = 0; j < 2; ++j) {
+ wizard1.setOption(QWizard::IgnoreSubTitles, j == 0);
+
+ wizard1.setWizardStyle(i == 0 ? QWizard::ClassicStyle
+ : i == 1 ? QWizard::ModernStyle
+ : QWizard::MacStyle);
+ wizard1.restart();
+ QImage i1 = grabWidget(&wizard1);
+
+ wizard1.next();
+ QImage i2 = grabWidget(&wizard1);
+
+ if (j == 0 || wizard1.wizardStyle() == QWizard::MacStyle) {
+ QVERIFY(i1 == i2);
+ } else {
+ QVERIFY(i1 != i2);
+ }
+ }
+ }
+}
+
+void tst_QWizard::setOption_ExtendedWatermarkPixmap()
+{
+#if defined(Q_OS_WINCE)
+ QSKIP("Skipped because of limited resources and potential crash. (Task: 166824)", SkipAll);
+#endif
+ QPixmap watermarkPixmap(200, 400);
+ watermarkPixmap.fill(Qt::black);
+
+ QWizard wizard1;
+ wizard1.setButtonLayout(QList<QWizard::WizardButton>() << QWizard::CancelButton);
+ QVERIFY(!wizard1.testOption(QWizard::ExtendedWatermarkPixmap));
+ QWizardPage *page11 = new QWizardPage;
+ page11->setTitle("Page X");
+ page11->setPixmap(QWizard::WatermarkPixmap, watermarkPixmap);
+
+ QWizardPage *page12 = new QWizardPage;
+ page12->setTitle("Page X");
+
+ wizard1.addPage(page11);
+ wizard1.addPage(page12);
+
+ QWizard wizard2;
+ wizard2.setButtonLayout(QList<QWizard::WizardButton>() << QWizard::CancelButton);
+ wizard2.setOption(QWizard::ExtendedWatermarkPixmap, true);
+ QWizardPage *page21 = new QWizardPage;
+ page21->setTitle("Page X");
+ page21->setPixmap(QWizard::WatermarkPixmap, watermarkPixmap);
+
+ QWizardPage *page22 = new QWizardPage;
+ page22->setTitle("Page X");
+
+ wizard2.addPage(page21);
+ wizard2.addPage(page22);
+
+ wizard1.show();
+ wizard2.show();
+
+ // Check the impact of watermark pixmaps on the rest of the layout.
+
+ for (int i = 0; i < 3; ++i) {
+ QImage i1[2];
+ QImage i2[2];
+ for (int j = 0; j < 2; ++j) {
+ wizard1.setOption(QWizard::ExtendedWatermarkPixmap, j == 0);
+
+ wizard1.setWizardStyle(i == 0 ? QWizard::ClassicStyle
+ : i == 1 ? QWizard::ModernStyle
+ : QWizard::MacStyle);
+ wizard1.restart();
+ wizard1.setMaximumSize(1000, 1000);
+ wizard1.resize(600, 600);
+ i1[j] = grabWidget(&wizard1);
+
+ wizard1.next();
+ wizard1.setMaximumSize(1000, 1000);
+ wizard1.resize(600, 600);
+ i2[j] = grabWidget(&wizard1);
+ }
+
+ if (wizard1.wizardStyle() == QWizard::MacStyle) {
+ QVERIFY(i1[0] == i1[1]);
+ QVERIFY(i2[0] == i2[1]);
+ QVERIFY(i1[0] == i2[0]);
+ } else {
+ QVERIFY(i1[0] != i1[1]);
+ QVERIFY(i2[0] == i2[1]);
+ QVERIFY(i1[0] != i2[0]);
+ QVERIFY(i1[1] != i2[1]);
+ }
+ }
+}
+
+void tst_QWizard::setOption_NoDefaultButton()
+{
+ QWizard wizard;
+ wizard.setOption(QWizard::NoDefaultButton, false);
+ wizard.setOption(QWizard::HaveFinishButtonOnEarlyPages, true);
+ wizard.addPage(new QWizardPage);
+ wizard.page(0)->setFinalPage(true);
+ wizard.addPage(new QWizardPage);
+
+ if (QPushButton *pb = qobject_cast<QPushButton *>(wizard.button(QWizard::NextButton)))
+ pb->setAutoDefault(false);
+ if (QPushButton *pb = qobject_cast<QPushButton *>(wizard.button(QWizard::FinishButton)))
+ pb->setAutoDefault(false);
+
+ wizard.show();
+ qApp->processEvents();
+ QVERIFY(qobject_cast<QPushButton *>(wizard.button(QWizard::NextButton))->isDefault());
+ QVERIFY(wizard.button(QWizard::FinishButton)->isEnabled());
+
+ wizard.next();
+ QVERIFY(qobject_cast<QPushButton *>(wizard.button(QWizard::FinishButton))->isDefault());
+
+ wizard.back();
+ QVERIFY(qobject_cast<QPushButton *>(wizard.button(QWizard::NextButton))->isDefault());
+
+ wizard.setOption(QWizard::NoDefaultButton, true);
+ QVERIFY(!qobject_cast<QPushButton *>(wizard.button(QWizard::NextButton))->isDefault());
+ QVERIFY(!qobject_cast<QPushButton *>(wizard.button(QWizard::FinishButton))->isDefault());
+
+ wizard.next();
+ QVERIFY(!qobject_cast<QPushButton *>(wizard.button(QWizard::NextButton))->isDefault());
+ QVERIFY(!qobject_cast<QPushButton *>(wizard.button(QWizard::FinishButton))->isDefault());
+
+ wizard.back();
+ QVERIFY(!qobject_cast<QPushButton *>(wizard.button(QWizard::NextButton))->isDefault());
+ QVERIFY(!qobject_cast<QPushButton *>(wizard.button(QWizard::FinishButton))->isDefault());
+
+ wizard.setOption(QWizard::NoDefaultButton, false);
+ QVERIFY(qobject_cast<QPushButton *>(wizard.button(QWizard::NextButton))->isDefault());
+}
+
+void tst_QWizard::setOption_NoBackButtonOnStartPage()
+{
+ QWizard wizard;
+ wizard.setOption(QWizard::NoBackButtonOnStartPage, true);
+ wizard.addPage(new QWizardPage);
+ wizard.addPage(new QWizardPage);
+ wizard.addPage(new QWizardPage);
+
+ wizard.setStartId(1);
+ wizard.show();
+ qApp->processEvents();
+
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.setOption(QWizard::NoBackButtonOnStartPage, false);
+ qApp->processEvents();
+ QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.setOption(QWizard::NoBackButtonOnStartPage, true);
+ qApp->processEvents();
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.next();
+ qApp->processEvents();
+ QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.setOption(QWizard::NoBackButtonOnStartPage, false);
+ QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.setOption(QWizard::NoBackButtonOnStartPage, true);
+ QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.back();
+ qApp->processEvents();
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+}
+
+void tst_QWizard::setOption_NoBackButtonOnLastPage()
+{
+ for (int i = 0; i < 2; ++i) {
+ QWizard wizard;
+ wizard.setOption(QWizard::NoBackButtonOnStartPage, false);
+ wizard.setOption(QWizard::NoBackButtonOnLastPage, true);
+ wizard.setOption(QWizard::DisabledBackButtonOnLastPage, i == 0); // changes nothing
+ wizard.addPage(new QWizardPage);
+ wizard.addPage(new QWizardPage);
+ wizard.page(1)->setFinalPage(true); // changes nothing (final != last in general)
+ wizard.addPage(new QWizardPage);
+
+ wizard.setStartId(1);
+ wizard.show();
+ qApp->processEvents();
+
+ QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.next();
+ qApp->processEvents();
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.next();
+ qApp->processEvents();
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.back();
+ qApp->processEvents();
+ QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.next();
+ qApp->processEvents();
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.setOption(QWizard::NoBackButtonOnLastPage, false);
+ QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.setOption(QWizard::NoBackButtonOnLastPage, true);
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.addPage(new QWizardPage);
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible()); // this is maybe wrong
+ }
+}
+
+void tst_QWizard::setOption_DisabledBackButtonOnLastPage()
+{
+ QWizard wizard;
+ wizard.setOption(QWizard::NoBackButtonOnStartPage, false);
+ wizard.setOption(QWizard::DisabledBackButtonOnLastPage, true);
+ wizard.addPage(new QWizardPage);
+ wizard.addPage(new QWizardPage);
+ wizard.page(1)->setFinalPage(true); // changes nothing (final != last in general)
+ wizard.addPage(new QWizardPage);
+
+ wizard.setStartId(1);
+ wizard.show();
+ qApp->processEvents();
+
+ QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
+
+ wizard.next();
+ qApp->processEvents();
+ QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
+
+ wizard.next();
+ qApp->processEvents();
+ QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
+
+ wizard.back();
+ qApp->processEvents();
+ QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
+
+ wizard.next();
+ qApp->processEvents();
+ QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
+
+ wizard.setOption(QWizard::DisabledBackButtonOnLastPage, false);
+ QVERIFY(wizard.button(QWizard::BackButton)->isEnabled());
+
+ wizard.setOption(QWizard::DisabledBackButtonOnLastPage, true);
+ QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
+
+ wizard.addPage(new QWizardPage);
+ QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled()); // this is maybe wrong
+}
+
+void tst_QWizard::setOption_HaveNextButtonOnLastPage()
+{
+ QWizard wizard;
+ wizard.setOption(QWizard::HaveNextButtonOnLastPage, false);
+ wizard.addPage(new QWizardPage);
+ wizard.addPage(new QWizardPage);
+ wizard.page(1)->setFinalPage(true); // changes nothing (final != last in general)
+ wizard.addPage(new QWizardPage);
+
+ wizard.setStartId(1);
+ wizard.show();
+ qApp->processEvents();
+
+ QVERIFY(wizard.button(QWizard::NextButton)->isVisible());
+ QVERIFY(wizard.button(QWizard::NextButton)->isEnabled());
+
+ wizard.next();
+ QVERIFY(!wizard.button(QWizard::NextButton)->isVisible());
+
+ wizard.setOption(QWizard::HaveNextButtonOnLastPage, true);
+ QVERIFY(wizard.button(QWizard::NextButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::NextButton)->isEnabled());
+
+ wizard.next();
+ QVERIFY(wizard.button(QWizard::NextButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::NextButton)->isEnabled());
+
+ wizard.back();
+ QVERIFY(wizard.button(QWizard::NextButton)->isVisible());
+ QVERIFY(wizard.button(QWizard::NextButton)->isEnabled());
+
+ wizard.setOption(QWizard::HaveNextButtonOnLastPage, false);
+ QVERIFY(wizard.button(QWizard::NextButton)->isVisible());
+ QVERIFY(wizard.button(QWizard::NextButton)->isEnabled());
+
+ wizard.next();
+ QVERIFY(!wizard.button(QWizard::NextButton)->isVisible());
+
+ wizard.setOption(QWizard::HaveNextButtonOnLastPage, true);
+ QVERIFY(wizard.button(QWizard::NextButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::NextButton)->isEnabled());
+}
+
+void tst_QWizard::setOption_HaveFinishButtonOnEarlyPages()
+{
+ QWizard wizard;
+ QVERIFY(!wizard.testOption(QWizard::HaveFinishButtonOnEarlyPages));
+ wizard.addPage(new QWizardPage);
+ wizard.addPage(new QWizardPage);
+ wizard.page(1)->setFinalPage(true);
+ wizard.addPage(new QWizardPage);
+
+ wizard.show();
+ qApp->processEvents();
+
+ QVERIFY(!wizard.button(QWizard::FinishButton)->isVisible());
+
+ wizard.next();
+ QVERIFY(wizard.button(QWizard::FinishButton)->isVisible());
+
+ wizard.next();
+ QVERIFY(wizard.button(QWizard::FinishButton)->isVisible());
+
+ wizard.back();
+ QVERIFY(wizard.button(QWizard::FinishButton)->isVisible());
+
+ wizard.back();
+ QVERIFY(!wizard.button(QWizard::FinishButton)->isVisible());
+
+ wizard.setOption(QWizard::HaveFinishButtonOnEarlyPages, true);
+ QVERIFY(wizard.button(QWizard::FinishButton)->isVisible());
+
+ wizard.next();
+ QVERIFY(wizard.button(QWizard::FinishButton)->isVisible());
+
+ wizard.setOption(QWizard::HaveFinishButtonOnEarlyPages, false);
+ QVERIFY(wizard.button(QWizard::FinishButton)->isVisible());
+
+ wizard.back();
+ QVERIFY(!wizard.button(QWizard::FinishButton)->isVisible());
+}
+
+void tst_QWizard::setOption_NoCancelButton()
+{
+ for (int i = 0; i < 2; ++i) {
+ QWizard wizard;
+ wizard.setOption(QWizard::NoCancelButton, true);
+ wizard.setOption(QWizard::CancelButtonOnLeft, i == 0);
+ wizard.addPage(new QWizardPage);
+ wizard.addPage(new QWizardPage);
+ wizard.show();
+ qApp->processEvents();
+
+ QVERIFY(!wizard.button(QWizard::CancelButton)->isVisible());
+
+ wizard.next();
+ QVERIFY(!wizard.button(QWizard::CancelButton)->isVisible());
+
+ wizard.setOption(QWizard::NoCancelButton, false);
+ QVERIFY(wizard.button(QWizard::CancelButton)->isVisible());
+
+ wizard.back();
+ QVERIFY(wizard.button(QWizard::CancelButton)->isVisible());
+
+ wizard.setOption(QWizard::NoCancelButton, true);
+ QVERIFY(!wizard.button(QWizard::CancelButton)->isVisible());
+ }
+}
+
+void tst_QWizard::setOption_CancelButtonOnLeft()
+{
+ for (int i = 0; i < 2; ++i) {
+ int sign = (i == 0) ? +1 : -1;
+
+ QWizard wizard;
+ wizard.setLayoutDirection(i == 0 ? Qt::LeftToRight : Qt::RightToLeft);
+ wizard.setOption(QWizard::NoCancelButton, false);
+ wizard.setOption(QWizard::CancelButtonOnLeft, true);
+ wizard.setOption(QWizard::NoBackButtonOnStartPage, false);
+ wizard.addPage(new QWizardPage);
+ wizard.addPage(new QWizardPage);
+ wizard.show();
+ qApp->processEvents();
+
+ const QAbstractButton *refButton = wizard.button((wizard.wizardStyle() == QWizard::AeroStyle)
+ ? QWizard::NextButton : QWizard::BackButton);
+ const QAbstractButton *refButton2 = wizard.button((wizard.wizardStyle() == QWizard::AeroStyle)
+ ? QWizard::FinishButton : QWizard::BackButton);
+
+ QVERIFY(sign * wizard.button(QWizard::CancelButton)->x() < sign * refButton->x());
+
+ wizard.next();
+ qApp->processEvents();
+ QVERIFY(sign * wizard.button(QWizard::CancelButton)->x() < sign * refButton->x());
+
+ wizard.setOption(QWizard::CancelButtonOnLeft, false);
+ qApp->processEvents();
+ QVERIFY(sign * wizard.button(QWizard::CancelButton)->x() > sign * refButton2->x());
+
+ wizard.back();
+ qApp->processEvents();
+ QVERIFY(sign * wizard.button(QWizard::CancelButton)->x() > sign * refButton->x());
+ }
+}
+
+void tst_QWizard::setOption_HaveHelpButton()
+{
+ for (int i = 0; i < 2; ++i) {
+ QWizard wizard;
+ QVERIFY(!wizard.testOption(QWizard::HaveHelpButton));
+ wizard.setOption(QWizard::HaveHelpButton, false);
+ wizard.setOption(QWizard::HelpButtonOnRight, i == 0);
+ wizard.addPage(new QWizardPage);
+ wizard.addPage(new QWizardPage);
+ wizard.show();
+ qApp->processEvents();
+
+ QVERIFY(!wizard.button(QWizard::HelpButton)->isVisible());
+
+ wizard.next();
+ QVERIFY(!wizard.button(QWizard::HelpButton)->isVisible());
+
+ wizard.setOption(QWizard::HaveHelpButton, true);
+ QVERIFY(wizard.button(QWizard::HelpButton)->isVisible());
+
+ wizard.back();
+ QVERIFY(wizard.button(QWizard::HelpButton)->isVisible());
+
+ wizard.setOption(QWizard::HaveHelpButton, false);
+ QVERIFY(!wizard.button(QWizard::HelpButton)->isVisible());
+ }
+}
+
+void tst_QWizard::setOption_HelpButtonOnRight()
+{
+ for (int i = 0; i < 2; ++i) {
+ int sign = (i == 0) ? +1 : -1;
+
+ QWizard wizard;
+ wizard.setLayoutDirection(i == 0 ? Qt::LeftToRight : Qt::RightToLeft);
+ wizard.setOption(QWizard::HaveHelpButton, true);
+ wizard.setOption(QWizard::HelpButtonOnRight, false);
+ wizard.setOption(QWizard::NoBackButtonOnStartPage, false);
+ wizard.addPage(new QWizardPage);
+ wizard.addPage(new QWizardPage);
+ wizard.show();
+ qApp->processEvents();
+
+ const QAbstractButton *refButton = wizard.button((wizard.wizardStyle() == QWizard::AeroStyle)
+ ? QWizard::NextButton : QWizard::BackButton);
+
+ QVERIFY(sign * wizard.button(QWizard::HelpButton)->x() < sign * refButton->x());
+
+ wizard.next();
+ qApp->processEvents();
+ QVERIFY(sign * wizard.button(QWizard::HelpButton)->x() < sign * refButton->x());
+
+ wizard.setOption(QWizard::HelpButtonOnRight, true);
+ qApp->processEvents();
+ QVERIFY(sign * wizard.button(QWizard::HelpButton)->x() > sign * refButton->x());
+
+ wizard.back();
+ qApp->processEvents();
+ QVERIFY(sign * wizard.button(QWizard::HelpButton)->x() > sign * refButton->x());
+ }
+}
+
+void tst_QWizard::setOption_HaveCustomButtonX()
+{
+ for (int i = 0; i < 2; ++i) {
+ for (int j = 0; j < 2; ++j) {
+ for (int k = 0; k < 2; ++k) {
+ QWizard wizard;
+ wizard.setLayoutDirection(Qt::LeftToRight);
+ wizard.addPage(new QWizardPage);
+ wizard.addPage(new QWizardPage);
+ wizard.show();
+
+ wizard.setButtonText(QWizard::CustomButton1, "Foo");
+ wizard.setButton(QWizard::CustomButton2, new QCheckBox("Bar"));
+ wizard.button(QWizard::CustomButton3)->setText("Baz");
+
+ wizard.setOption(QWizard::HaveCustomButton1, i == 0);
+ wizard.setOption(QWizard::HaveCustomButton2, j == 0);
+ wizard.setOption(QWizard::HaveCustomButton3, k == 0);
+
+ QVERIFY(wizard.button(QWizard::CustomButton1)->isHidden() == (i != 0));
+ QVERIFY(wizard.button(QWizard::CustomButton2)->isHidden() == (j != 0));
+ QVERIFY(wizard.button(QWizard::CustomButton3)->isHidden() == (k != 0));
+
+ if (i + j + k == 0) {
+ qApp->processEvents();
+ QVERIFY(wizard.button(QWizard::CustomButton1)->x()
+ < wizard.button(QWizard::CustomButton2)->x());
+ QVERIFY(wizard.button(QWizard::CustomButton2)->x()
+ < wizard.button(QWizard::CustomButton3)->x());
+ }
+ }
+ }
+ }
+}
+
+class Operation
+{
+public:
+ virtual void apply(QWizard *) const = 0;
+ virtual QString describe() const = 0;
+protected:
+ virtual ~Operation() {}
+};
+
+class SetPage : public Operation
+{
+ void apply(QWizard *wizard) const
+ {
+ wizard->restart();
+ for (int j = 0; j < page; ++j)
+ wizard->next();
+ }
+ QString describe() const { return QString("set page %1").arg(page); }
+ const int page;
+public:
+ SetPage(int page) : page(page) {}
+};
+
+class SetStyle : public Operation
+{
+ void apply(QWizard *wizard) const { wizard->setWizardStyle(style); }
+ QString describe() const { return QString("set style %1").arg(style); }
+ const QWizard::WizardStyle style;
+public:
+ SetStyle(QWizard::WizardStyle style) : style(style) {}
+};
+
+class SetOption : public Operation
+{
+ void apply(QWizard *wizard) const { wizard->setOption(option, on); }
+ QString describe() const;
+ const QWizard::WizardOption option;
+ const bool on;
+public:
+ SetOption(QWizard::WizardOption option, bool on) : option(option), on(on) {}
+};
+
+class OptionInfo
+{
+ OptionInfo()
+ {
+ tags[QWizard::IndependentPages] = "0/IPP";
+ tags[QWizard::IgnoreSubTitles] = "1/IST";
+ tags[QWizard::ExtendedWatermarkPixmap] = "2/EWP";
+ tags[QWizard::NoDefaultButton] = "3/NDB";
+ tags[QWizard::NoBackButtonOnStartPage] = "4/BSP";
+ tags[QWizard::NoBackButtonOnLastPage] = "5/BLP";
+ tags[QWizard::DisabledBackButtonOnLastPage] = "6/DLP";
+ tags[QWizard::HaveNextButtonOnLastPage] = "7/NLP";
+ tags[QWizard::HaveFinishButtonOnEarlyPages] = "8/FEP";
+ tags[QWizard::NoCancelButton] = "9/NCB";
+ tags[QWizard::CancelButtonOnLeft] = "10/CBL";
+ tags[QWizard::HaveHelpButton] = "11/HHB";
+ tags[QWizard::HelpButtonOnRight] = "12/HBR";
+ tags[QWizard::HaveCustomButton1] = "13/CB1";
+ tags[QWizard::HaveCustomButton2] = "14/CB2";
+ tags[QWizard::HaveCustomButton3] = "15/CB3";
+
+ for (int i = 0; i < 2; ++i) {
+ QMap<QWizard::WizardOption, Operation *> operations_;
+ foreach (QWizard::WizardOption option, tags.keys())
+ operations_[option] = new SetOption(option, i == 1);
+ operations << operations_;
+ }
+ }
+ OptionInfo(OptionInfo const&);
+ OptionInfo& operator=(OptionInfo const&);
+ QMap<QWizard::WizardOption, QString> tags;
+ QList<QMap<QWizard::WizardOption, Operation *> > operations;
+public:
+ static OptionInfo &instance()
+ {
+ static OptionInfo optionInfo;
+ return optionInfo;
+ }
+
+ QString tag(QWizard::WizardOption option) const { return tags.value(option); }
+ Operation * operation(QWizard::WizardOption option, bool on) const
+ { return operations.at(on).value(option); }
+ QList<QWizard::WizardOption> options() const { return tags.keys(); }
+};
+
+QString SetOption::describe() const
+{
+ return QString("set opt %1 %2").arg(OptionInfo::instance().tag(option)).arg(on);
+}
+
+Q_DECLARE_METATYPE(Operation *)
+Q_DECLARE_METATYPE(SetPage *)
+Q_DECLARE_METATYPE(SetStyle *)
+Q_DECLARE_METATYPE(SetOption *)
+Q_DECLARE_METATYPE(QList<Operation *>)
+
+class TestGroup
+{
+public:
+ enum Type {Equality, NonEquality};
+
+ TestGroup(const QString &name = QString("no name"), Type type = Equality)
+ : name(name), type(type), nRows_(0) {}
+
+ void reset(const QString &name, Type type = Equality)
+ {
+ this->name = name;
+ this->type = type;
+ combinations.clear();
+ }
+
+ QList<Operation *> &add()
+ { combinations << new QList<Operation *>; return *(combinations.last()); }
+
+ void createTestRows()
+ {
+ for (int i = 0; i < combinations.count(); ++i) {
+ QTest::newRow((name + QString(", row %1").arg(i)).toLatin1().data())
+ << (i == 0) << (type == Equality) << *(combinations.at(i));
+ ++nRows_;
+ }
+ }
+
+ int nRows() const { return nRows_; }
+
+private:
+ QString name;
+ Type type;
+ int nRows_;
+ QList<QList<Operation *> *> combinations;
+};
+
+class IntroPage : public QWizardPage
+{
+ Q_OBJECT
+public:
+ IntroPage()
+ {
+ setTitle(tr("Intro"));
+ setSubTitle(tr("Intro Subtitle"));
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addWidget(new QLabel(tr("Intro Label")));
+ setLayout(layout);
+ }
+};
+
+class MiddlePage : public QWizardPage
+{
+ Q_OBJECT
+public:
+ MiddlePage()
+ {
+ setTitle(tr("Middle"));
+ setSubTitle(tr("Middle Subtitle"));
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addWidget(new QLabel(tr("Middle Label")));
+ setLayout(layout);
+ }
+};
+
+class ConclusionPage : public QWizardPage
+{
+ Q_OBJECT
+public:
+ ConclusionPage()
+ {
+ setTitle(tr("Conclusion"));
+ setSubTitle(tr("Conclusion Subtitle"));
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addWidget(new QLabel(tr("Conclusion Label")));
+ setLayout(layout);
+ }
+};
+
+class TestWizard : public QWizard
+{
+ Q_OBJECT
+ QList<int> pageIds;
+ QString opsDescr;
+public:
+ TestWizard()
+ {
+ setPixmap(QWizard::BannerPixmap, QPixmap(":/images/banner.png"));
+ setPixmap(QWizard::BackgroundPixmap, QPixmap(":/images/background.png"));
+ setPixmap(QWizard::WatermarkPixmap, QPixmap(":/images/watermark.png"));
+ setPixmap(QWizard::LogoPixmap, QPixmap(":/images/logo.png"));
+ setButtonText(QWizard::CustomButton1, "custom 1");
+ setButtonText(QWizard::CustomButton2, "custom 2");
+ setButtonText(QWizard::CustomButton3, "custom 3");
+ pageIds << addPage(new IntroPage);
+ pageIds << addPage(new MiddlePage);
+ pageIds << addPage(new ConclusionPage);
+
+ // Disable antialiased font rendering since this may sometimes result in tiny
+ // and (apparent) non-deterministic pixel variations between images expected to be
+ // identical. This may only be a problem on X11.
+ QFont f = font();
+ f.setStyleStrategy(QFont::NoAntialias);
+ setFont(f);
+
+ // ### Required to work with a deficiency(?) in QWizard:
+// setFixedSize(800, 600);
+ }
+
+ ~TestWizard()
+ {
+ foreach (int id, pageIds) {
+ QWizardPage *page_to_delete = page(id);
+ removePage(id);
+ delete page_to_delete;
+ }
+ }
+
+ void applyOperations(const QList<Operation *> &operations)
+ {
+ foreach (Operation * op, operations) {
+ if (op) {
+ op->apply(this);
+ opsDescr += QString("(%1) ").arg(op->describe());
+ }
+ }
+ }
+
+ QImage createImage() const
+ {
+ return QPixmap::grabWidget(const_cast<TestWizard *>(this))
+ .toImage().convertToFormat(QImage::Format_ARGB32);
+ }
+
+ QString operationsDescription() const { return opsDescr; }
+};
+
+class CombinationsTestData
+{
+ TestGroup testGroup;
+ QList<Operation *> pageOps;
+ QList<Operation *> styleOps;
+ QMap<bool, QList<Operation *> *> setAllOptions;
+public:
+ CombinationsTestData()
+ {
+ QTest::addColumn<bool>("ref");
+ QTest::addColumn<bool>("testEquality");
+ QTest::addColumn<QList<Operation *> >("operations");
+ pageOps << new SetPage(0) << new SetPage(1) << new SetPage(2);
+ styleOps << new SetStyle(QWizard::ClassicStyle) << new SetStyle(QWizard::ModernStyle)
+ << new SetStyle(QWizard::MacStyle);
+#define SETPAGE(page) pageOps.at(page)
+#define SETSTYLE(style) styleOps.at(style)
+#define OPT(option, on) OptionInfo::instance().operation(option, on)
+#define CLROPT(option) OPT(option, false)
+#define SETOPT(option) OPT(option, true)
+ setAllOptions[false] = new QList<Operation *>;
+ setAllOptions[true] = new QList<Operation *>;
+ foreach (QWizard::WizardOption option, OptionInfo::instance().options()) {
+ *setAllOptions.value(false) << CLROPT(option);
+ *setAllOptions.value(true) << SETOPT(option);
+ }
+#define CLRALLOPTS *setAllOptions.value(false)
+#define SETALLOPTS *setAllOptions.value(true)
+ }
+
+ int nRows() const { return testGroup.nRows(); }
+
+ // Creates "all" possible test rows. (WARNING: This typically makes the test take too long!)
+ void createAllTestRows()
+ {
+ testGroup.reset("testAll 1.1");
+ testGroup.add(); // i.e. no operations applied!
+ testGroup.add() << SETPAGE(0);
+ testGroup.add() << SETSTYLE(0);
+ testGroup.add() << SETPAGE(0) << SETSTYLE(0);
+ testGroup.add() << SETSTYLE(0) << SETPAGE(0);
+ testGroup.createTestRows();
+
+ testGroup.reset("testAll 2.1");
+ testGroup.add();
+ testGroup.add() << CLRALLOPTS;
+ testGroup.createTestRows();
+
+ testGroup.reset("testAll 2.2");
+ testGroup.add() << SETALLOPTS;
+ testGroup.add() << SETALLOPTS << SETALLOPTS;
+ testGroup.createTestRows();
+
+ testGroup.reset("testAll 2.3");
+ testGroup.add() << CLRALLOPTS;
+ testGroup.add() << CLRALLOPTS << CLRALLOPTS;
+ testGroup.createTestRows();
+
+ testGroup.reset("testAll 2.4");
+ testGroup.add() << CLRALLOPTS;
+ testGroup.add() << SETALLOPTS << CLRALLOPTS;
+ testGroup.createTestRows();
+
+ testGroup.reset("testAll 2.5");
+ testGroup.add() << SETALLOPTS;
+ testGroup.add() << CLRALLOPTS << SETALLOPTS;
+ testGroup.createTestRows();
+
+ testGroup.reset("testAll 2.6");
+ testGroup.add() << SETALLOPTS;
+ testGroup.add() << SETALLOPTS << CLRALLOPTS << SETALLOPTS;
+ testGroup.createTestRows();
+
+ testGroup.reset("testAll 2.7");
+ testGroup.add() << CLRALLOPTS;
+ testGroup.add() << CLRALLOPTS << SETALLOPTS << CLRALLOPTS;
+ testGroup.createTestRows();
+
+ for (int i = 0; i < 2; ++i) {
+ QList<Operation *> setOptions = *setAllOptions.value(i == 1);
+
+ testGroup.reset("testAll 3.1");
+ testGroup.add() << setOptions;
+ testGroup.add() << SETPAGE(0) << setOptions;
+ testGroup.add() << setOptions << SETPAGE(0);
+ testGroup.add() << SETSTYLE(0) << setOptions;
+ testGroup.add() << setOptions << SETSTYLE(0);
+ testGroup.add() << setOptions << SETPAGE(0) << SETSTYLE(0);
+ testGroup.add() << SETPAGE(0) << setOptions << SETSTYLE(0);
+ testGroup.add() << SETPAGE(0) << SETSTYLE(0) << setOptions;
+ testGroup.add() << setOptions << SETSTYLE(0) << SETPAGE(0);
+ testGroup.add() << SETSTYLE(0) << setOptions << SETPAGE(0);
+ testGroup.add() << SETSTYLE(0) << SETPAGE(0) << setOptions;
+ testGroup.createTestRows();
+ }
+
+ foreach (Operation *pageOp, pageOps) {
+ testGroup.reset("testAll 4.1");
+ testGroup.add() << pageOp;
+ testGroup.add() << pageOp << pageOp;
+ testGroup.createTestRows();
+
+ for (int i = 0; i < 2; ++i) {
+ QList<Operation *> optionOps = *setAllOptions.value(i == 1);
+ testGroup.reset("testAll 4.2");
+ testGroup.add() << optionOps << pageOp;
+ testGroup.add() << pageOp << optionOps;
+ testGroup.createTestRows();
+
+ foreach (QWizard::WizardOption option, OptionInfo::instance().options()) {
+ Operation *optionOp = OPT(option, i == 1);
+ testGroup.reset("testAll 4.3");
+ testGroup.add() << optionOp << pageOp;
+ testGroup.add() << pageOp << optionOp;
+ testGroup.createTestRows();
+ }
+ }
+ }
+
+ foreach (Operation *styleOp, styleOps) {
+ testGroup.reset("testAll 5.1");
+ testGroup.add() << styleOp;
+ testGroup.add() << styleOp << styleOp;
+ testGroup.createTestRows();
+
+ for (int i = 0; i < 2; ++i) {
+ QList<Operation *> optionOps = *setAllOptions.value(i == 1);
+ testGroup.reset("testAll 5.2");
+ testGroup.add() << optionOps << styleOp;
+ testGroup.add() << styleOp << optionOps;
+ testGroup.createTestRows();
+
+ foreach (QWizard::WizardOption option, OptionInfo::instance().options()) {
+ Operation *optionOp = OPT(option, i == 1);
+ testGroup.reset("testAll 5.3");
+ testGroup.add() << optionOp << styleOp;
+ testGroup.add() << styleOp << optionOp;
+ testGroup.createTestRows();
+ }
+ }
+ }
+
+ foreach (Operation *pageOp, pageOps) {
+ foreach (Operation *styleOp, styleOps) {
+
+ testGroup.reset("testAll 6.1");
+ testGroup.add() << pageOp;
+ testGroup.add() << pageOp << pageOp;
+ testGroup.createTestRows();
+
+ testGroup.reset("testAll 6.2");
+ testGroup.add() << styleOp;
+ testGroup.add() << styleOp << styleOp;
+ testGroup.createTestRows();
+
+ testGroup.reset("testAll 6.3");
+ testGroup.add() << pageOp << styleOp;
+ testGroup.add() << styleOp << pageOp;
+ testGroup.createTestRows();
+
+ for (int i = 0; i < 2; ++i) {
+ QList<Operation *> optionOps = *setAllOptions.value(i == 1);
+ testGroup.reset("testAll 6.4");
+ testGroup.add() << optionOps << pageOp << styleOp;
+ testGroup.add() << pageOp << optionOps << styleOp;
+ testGroup.add() << pageOp << styleOp << optionOps;
+ testGroup.add() << optionOps << styleOp << pageOp;
+ testGroup.add() << styleOp << optionOps << pageOp;
+ testGroup.add() << styleOp << pageOp << optionOps;
+ testGroup.createTestRows();
+
+ foreach (QWizard::WizardOption option, OptionInfo::instance().options()) {
+ Operation *optionOp = OPT(option, i == 1);
+ testGroup.reset("testAll 6.5");
+ testGroup.add() << optionOp << pageOp << styleOp;
+ testGroup.add() << pageOp << optionOp << styleOp;
+ testGroup.add() << pageOp << styleOp << optionOp;
+ testGroup.add() << optionOp << styleOp << pageOp;
+ testGroup.add() << styleOp << optionOp << pageOp;
+ testGroup.add() << styleOp << pageOp << optionOp;
+ testGroup.createTestRows();
+ }
+ }
+ }
+ }
+
+ testGroup.reset("testAll 7.1", TestGroup::NonEquality);
+ testGroup.add() << SETPAGE(0);
+ testGroup.add() << SETPAGE(1);
+ testGroup.add() << SETPAGE(2);
+ testGroup.createTestRows();
+
+ testGroup.reset("testAll 7.2", TestGroup::NonEquality);
+ testGroup.add() << SETSTYLE(0);
+ testGroup.add() << SETSTYLE(1);
+ testGroup.add() << SETSTYLE(2);
+ testGroup.createTestRows();
+
+ // more to follow ...
+ }
+
+ // Creates a "small" number of interesting test rows.
+ void createTestRows1()
+ {
+ testGroup.reset("test1 1");
+ testGroup.add() << SETPAGE(0) << SETOPT(QWizard::HaveCustomButton3);
+ testGroup.add() << SETOPT(QWizard::HaveCustomButton3);
+ testGroup.createTestRows();
+
+ testGroup.reset("test1 2");
+ testGroup.add() << SETOPT(QWizard::HaveFinishButtonOnEarlyPages) << SETPAGE(0);
+ testGroup.add() << SETPAGE(0) << SETOPT(QWizard::HaveFinishButtonOnEarlyPages);
+ testGroup.createTestRows();
+
+ testGroup.reset("test1 3");
+ testGroup.add() << SETPAGE(2) << SETOPT(QWizard::HaveNextButtonOnLastPage);
+ testGroup.add() << SETOPT(QWizard::HaveNextButtonOnLastPage) << SETPAGE(2);
+ testGroup.createTestRows();
+ }
+};
+
+// Too much memory usage for testing on CE emulator.
+#ifndef Q_OS_WINCE
+void tst_QWizard::combinations_data()
+{
+ CombinationsTestData combTestData;
+// combTestData.createAllTestRows();
+ combTestData.createTestRows1();
+
+// qDebug() << "test rows:" << combTestData.nRows();
+}
+
+void tst_QWizard::combinations()
+{
+ QFETCH(bool, ref);
+ QFETCH(bool, testEquality);
+ QFETCH(QList<Operation *>, operations);
+
+ TestWizard wizard;
+#if !defined(QT_NO_STYLE_WINDOWSVISTA)
+ if (wizard.wizardStyle() == QWizard::AeroStyle)
+ return; // ### TODO: passes/fails in a unpredictable way, so disable for now
+#endif
+ wizard.applyOperations(operations);
+ wizard.show(); // ### TODO: Required, but why? Should wizard.createImage() care?
+
+ static QImage refImage;
+ static QSize refMinSize;
+ static QString refDescr;
+
+ if (ref) {
+ refImage = wizard.createImage();
+ refMinSize = wizard.minimumSizeHint();
+ refDescr = wizard.operationsDescription();
+ return;
+ }
+
+ QImage image = wizard.createImage();
+
+ bool minSizeTest = wizard.minimumSizeHint() != refMinSize;
+ bool imageTest = image != refImage;
+ QLatin1String otor("!=");
+ QLatin1String reason("differ");
+
+ if (!testEquality) {
+ minSizeTest = false; // the image test is sufficient!
+ imageTest = !imageTest;
+ otor = QLatin1String("==");
+ reason = QLatin1String("are equal");
+ }
+
+ if (minSizeTest)
+ qDebug() << "minimum sizes" << reason.latin1() << ";" << wizard.minimumSizeHint()
+ << otor.latin1() << refMinSize;
+
+ if (imageTest)
+ qDebug() << "images" << reason.latin1();
+
+ if (minSizeTest || imageTest) {
+ qDebug() << "\t row 0 operations:" << refDescr.toLatin1();
+ qDebug() << "\tcurrent row operations:" << wizard.operationsDescription().toLatin1();
+ QVERIFY(false);
+ }
+}
+#endif
+
+class WizardPage : public QWizardPage
+{
+ Q_OBJECT
+ bool shown_;
+ void showEvent(QShowEvent *) { shown_ = true; }
+ void hideEvent(QHideEvent *) { shown_ = false; }
+public:
+ WizardPage() : shown_(false) {}
+ bool shown() const { return shown_; }
+};
+
+class WizardPages
+{
+ QList<WizardPage *> pages;
+public:
+ void add(WizardPage *page) { pages << page; }
+ QList<WizardPage *> all() const { return pages; }
+ QList<WizardPage *> shown() const
+ {
+ QList<WizardPage *> result;
+ foreach (WizardPage *page, pages)
+ if (page->shown())
+ result << page;
+ return result;
+ }
+};
+
+void tst_QWizard::showCurrentPageOnly()
+{
+ QWizard wizard;
+ WizardPages pages;
+ for (int i = 0; i < 5; ++i) {
+ pages.add(new WizardPage);
+ wizard.addPage(pages.all().last());
+ }
+
+ wizard.show();
+
+ QCOMPARE(pages.shown().count(), 1);
+ QCOMPARE(pages.shown().first(), pages.all().first());
+
+ const int steps = 2;
+ for (int i = 0; i < steps; ++i)
+ wizard.next();
+
+ QCOMPARE(pages.shown().count(), 1);
+ QCOMPARE(pages.shown().first(), pages.all().at(steps));
+
+ wizard.restart();
+
+ QCOMPARE(pages.shown().count(), 1);
+ QCOMPARE(pages.shown().first(), pages.all().first());
+}
+
+void tst_QWizard::setButtonText()
+{
+ QWizard wizard;
+ wizard.setWizardStyle(QWizard::ClassicStyle);
+ QWizardPage* page1 = new QWizardPage;
+ QWizardPage* page2 = new QWizardPage;
+ wizard.addPage(page1);
+ wizard.addPage(page2);
+
+ wizard.show();
+ qApp->processEvents();
+ QVERIFY(wizard.button(QWizard::NextButton)->text().contains("Next"));
+ QVERIFY(wizard.buttonText(QWizard::NextButton).contains("Next"));
+ QVERIFY(page1->buttonText(QWizard::NextButton).contains("Next"));
+ QVERIFY(page2->buttonText(QWizard::NextButton).contains("Next"));
+
+ page2->setButtonText(QWizard::NextButton, "Page2");
+ QVERIFY(wizard.button(QWizard::NextButton)->text().contains("Next"));
+ QVERIFY(wizard.buttonText(QWizard::NextButton).contains("Next"));
+ QVERIFY(page1->buttonText(QWizard::NextButton).contains("Next"));
+ QCOMPARE(page2->buttonText(QWizard::NextButton), QString("Page2"));
+
+ wizard.next();
+ qApp->processEvents();
+ QCOMPARE(wizard.button(QWizard::NextButton)->text(), QString("Page2"));
+ QVERIFY(wizard.buttonText(QWizard::NextButton).contains("Next"));
+ QVERIFY(page1->buttonText(QWizard::NextButton).contains("Next"));
+ QCOMPARE(page2->buttonText(QWizard::NextButton), QString("Page2"));
+
+ wizard.back();
+ qApp->processEvents();
+ QVERIFY(wizard.button(QWizard::NextButton)->text().contains("Next"));
+ QVERIFY(wizard.buttonText(QWizard::NextButton).contains("Next"));
+ QVERIFY(page1->buttonText(QWizard::NextButton).contains("Next"));
+ QCOMPARE(page2->buttonText(QWizard::NextButton), QString("Page2"));
+
+ wizard.setButtonText(QWizard::NextButton, "Wizard");
+ QVERIFY(wizard.button(QWizard::NextButton)->text().contains("Wizard"));
+ QCOMPARE(wizard.buttonText(QWizard::NextButton), QString("Wizard"));
+ QCOMPARE(page1->buttonText(QWizard::NextButton), QString("Wizard"));
+ QCOMPARE(page2->buttonText(QWizard::NextButton), QString("Page2"));
+
+ wizard.next();
+ qApp->processEvents();
+ QCOMPARE(wizard.button(QWizard::NextButton)->text(), QString("Page2"));
+ QVERIFY(wizard.buttonText(QWizard::NextButton).contains("Wizard"));
+ QCOMPARE(page1->buttonText(QWizard::NextButton), QString("Wizard"));
+ QCOMPARE(page2->buttonText(QWizard::NextButton), QString("Page2"));
+}
+
+void tst_QWizard::setCommitPage()
+{
+ QWizard wizard;
+ QWizardPage* page1 = new QWizardPage;
+ QWizardPage* page2 = new QWizardPage;
+ wizard.addPage(page1);
+ wizard.addPage(page2);
+ wizard.show();
+ qApp->processEvents();
+
+ QVERIFY(!page1->isCommitPage());
+ QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
+
+ wizard.next();
+ QVERIFY(wizard.button(QWizard::BackButton)->isEnabled());
+
+ page1->setCommitPage(true);
+ QVERIFY(page1->isCommitPage());
+
+ wizard.back();
+ QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
+
+ wizard.next();
+ QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
+
+ page1->setCommitPage(false);
+ QVERIFY(!page1->isCommitPage());
+
+ wizard.back();
+ QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
+
+ wizard.next();
+ QVERIFY(wizard.button(QWizard::BackButton)->isEnabled());
+
+ // ### test relabeling of the Cancel button to "Close" once this is implemented
+}
+
+void tst_QWizard::setWizardStyle()
+{
+ QWizard wizard;
+ wizard.addPage(new QWizardPage);
+ wizard.show();
+ qApp->processEvents();
+
+ // defaults
+ const bool styleHintMatch =
+ wizard.wizardStyle() ==
+ QWizard::WizardStyle(wizard.style()->styleHint(QStyle::SH_WizardStyle, 0, &wizard));
+#if !defined(QT_NO_STYLE_WINDOWSVISTA)
+ QVERIFY(styleHintMatch || wizard.wizardStyle() == QWizard::AeroStyle);
+#else
+ QVERIFY(styleHintMatch);
+#endif
+
+ // set/get consistency
+ for (int wstyle = 0; wstyle < QWizard::NStyles; ++wstyle) {
+ wizard.setWizardStyle((QWizard::WizardStyle)wstyle);
+ QCOMPARE((int)wizard.wizardStyle(), wstyle);
+ }
+}
+
+void tst_QWizard::removePage()
+{
+ QWizard wizard;
+ QWizardPage *page0 = new QWizardPage;
+ QWizardPage *page1 = new QWizardPage;
+ QWizardPage *page2 = new QWizardPage;
+ QWizardPage *page3 = new QWizardPage;
+ QSignalSpy spy(&wizard, SIGNAL(pageRemoved(int)));
+
+ wizard.setPage(0, page0);
+ wizard.setPage(1, page1);
+ wizard.setPage(2, page2);
+ wizard.setPage(3, page3);
+
+ wizard.restart();
+ QCOMPARE(wizard.pageIds().size(), 4);
+ QCOMPARE(wizard.visitedPages().size(), 1);
+ QCOMPARE(spy.count(), 0);
+
+ // Removing a non-existent page
+ wizard.removePage(4);
+ QCOMPARE(wizard.pageIds().size(), 4);
+ QCOMPARE(spy.count(), 0);
+
+ // Removing and then reinserting a page
+ QCOMPARE(wizard.pageIds().size(), 4);
+ QVERIFY(wizard.pageIds().contains(2));
+ wizard.removePage(2);
+ QCOMPARE(spy.count(), 1);
+ QList<QVariant> arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), 2);
+ QCOMPARE(wizard.pageIds().size(), 3);
+ QVERIFY(!wizard.pageIds().contains(2));
+ wizard.setPage(2, page2);
+ QCOMPARE(spy.count(), 0);
+ QCOMPARE(wizard.pageIds().size(), 4);
+ QVERIFY(wizard.pageIds().contains(2));
+
+ // Removing the same page twice
+ wizard.removePage(2); // restore
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), 2);
+ QCOMPARE(wizard.pageIds().size(), 3);
+ QVERIFY(!wizard.pageIds().contains(2));
+ wizard.removePage(2);
+ QCOMPARE(spy.count(), 0);
+ QCOMPARE(wizard.pageIds().size(), 3);
+ QVERIFY(!wizard.pageIds().contains(2));
+
+ // Removing a page not in the history
+ wizard.setPage(2, page2); // restore
+ wizard.restart();
+ wizard.next();
+ QCOMPARE(wizard.visitedPages().size(), 2);
+ QCOMPARE(wizard.currentPage(), page1);
+ QCOMPARE(spy.count(), 0);
+ wizard.removePage(2);
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), 2);
+ QCOMPARE(wizard.visitedPages().size(), 2);
+ QVERIFY(!wizard.pageIds().contains(2));
+ QCOMPARE(wizard.currentPage(), page1);
+
+ // Removing a page in the history before the current page
+ wizard.setPage(2, page2); // restore
+ wizard.restart();
+ wizard.next();
+ QCOMPARE(spy.count(), 0);
+ QCOMPARE(wizard.visitedPages().size(), 2);
+ QCOMPARE(wizard.currentPage(), page1);
+ wizard.removePage(0);
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), 0);
+ QCOMPARE(wizard.visitedPages().size(), 1);
+ QVERIFY(!wizard.visitedPages().contains(0));
+ QVERIFY(!wizard.pageIds().contains(0));
+ QCOMPARE(wizard.currentPage(), page1);
+
+ // Remove the current page which is not the first one in the history
+ wizard.setPage(0, page0); // restore
+ wizard.restart();
+ wizard.next();
+ QCOMPARE(spy.count(), 0);
+ QCOMPARE(wizard.visitedPages().size(), 2);
+ QCOMPARE(wizard.currentPage(), page1);
+ wizard.removePage(1);
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), 1);
+ QCOMPARE(wizard.visitedPages().size(), 1);
+ QVERIFY(!wizard.visitedPages().contains(1));
+ QVERIFY(!wizard.pageIds().contains(1));
+ QCOMPARE(wizard.currentPage(), page0);
+
+ // Remove the current page which is the first (and only) one in the history
+ wizard.removePage(0);
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), 0);
+ QCOMPARE(wizard.visitedPages().size(), 1);
+ QVERIFY(!wizard.visitedPages().contains(0));
+ QCOMPARE(wizard.pageIds().size(), 2);
+ QVERIFY(!wizard.pageIds().contains(0));
+ QCOMPARE(wizard.currentPage(), page2);
+ //
+ wizard.removePage(2);
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), 2);
+ QCOMPARE(wizard.visitedPages().size(), 1);
+ QVERIFY(!wizard.visitedPages().contains(2));
+ QCOMPARE(wizard.pageIds().size(), 1);
+ QVERIFY(!wizard.pageIds().contains(2));
+ QCOMPARE(wizard.currentPage(), page3);
+ //
+ wizard.removePage(3);
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), 3);
+ QVERIFY(wizard.visitedPages().empty());
+ QVERIFY(wizard.pageIds().empty());
+ QCOMPARE(wizard.currentPage(), static_cast<QWizardPage *>(0));
+}
+
+void tst_QWizard::sideWidget()
+{
+ QWizard wizard;
+
+ wizard.setSideWidget(0);
+ QVERIFY(wizard.sideWidget() == 0);
+ QWidget *w1 = new QWidget(&wizard);
+ wizard.setSideWidget(w1);
+ QVERIFY(wizard.sideWidget() == w1);
+ QWidget *w2 = new QWidget(&wizard);
+ wizard.setSideWidget(w2);
+ QVERIFY(wizard.sideWidget() == w2);
+ QVERIFY(w1->parent() != 0);
+ QCOMPARE(w1->window(), static_cast<QWidget *>(&wizard));
+ QCOMPARE(w2->window(), static_cast<QWidget *>(&wizard));
+ w1->setParent(0);
+ wizard.setSideWidget(0);
+ QVERIFY(wizard.sideWidget() == 0);
+}
+
+void tst_QWizard::task161660_buttonSpacing()
+{
+#ifndef QT_NO_STYLE_PLASTIQUE
+ QString origStyle = QApplication::style()->objectName();
+ QApplication::setStyle(new QPlastiqueStyle);
+ QWizard wizard;
+ wizard.addPage(new QWizardPage);
+ wizard.show();
+ const QAbstractButton *finishButton = wizard.button(QWizard::FinishButton);
+ const QAbstractButton *cancelButton = wizard.button(QWizard::CancelButton);
+ const int spacing = cancelButton->geometry().left() - finishButton->geometry().right() - 1;
+ QCOMPARE(spacing, wizard.style()->layoutSpacing(
+ QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal));
+ QApplication::setStyle(origStyle);
+#endif
+}
+
+class task177716_CommitPage : public QWizardPage
+{
+ Q_OBJECT
+public:
+ task177716_CommitPage()
+ {
+ setCommitPage(true);
+ QVBoxLayout *layout = new QVBoxLayout;
+ ledit = new QLineEdit(this);
+ registerField("foo*", ledit);
+ layout->addWidget(ledit);
+ setLayout(layout);
+ }
+ QLineEdit *ledit;
+};
+
+void tst_QWizard::task177716_disableCommitButton()
+{
+ QWizard wizard;
+ task177716_CommitPage *commitPage = new task177716_CommitPage;
+ wizard.addPage(commitPage);
+ // the following page must be there to prevent the first page from replacing the Commit button
+ // with the Finish button:
+ wizard.addPage(new QWizardPage);
+ wizard.show();
+ QVERIFY(!wizard.button(QWizard::CommitButton)->isEnabled());
+ commitPage->ledit->setText("some non-empty text");
+ QVERIFY(wizard.button(QWizard::CommitButton)->isEnabled());
+ commitPage->ledit->setText("");
+ QVERIFY(!wizard.button(QWizard::CommitButton)->isEnabled());
+}
+
+class WizardPage_task183550 : public QWizardPage
+{
+public:
+ WizardPage_task183550(QWidget *parent = 0)
+ : QWizardPage(parent)
+ , treeWidget(new QTreeWidget)
+ , verticalPolicy(QSizePolicy::MinimumExpanding) {}
+ void enableVerticalExpansion() { verticalPolicy = QSizePolicy::MinimumExpanding; }
+ void disableVerticalExpansion() { verticalPolicy = QSizePolicy::Preferred; }
+ int treeWidgetHeight() const { return treeWidget->height(); }
+ int treeWidgetSizeHintHeight() const { return treeWidget->sizeHint().height(); }
+
+private:
+ QTreeWidget *treeWidget;
+ QSizePolicy::Policy verticalPolicy;
+
+ void initializePage()
+ {
+ if (layout())
+ delete layout();
+ if (treeWidget)
+ delete treeWidget;
+
+ QLayout *layout_ = new QVBoxLayout(this);
+ layout_->addWidget(treeWidget = new QTreeWidget);
+
+ QSizePolicy policy = sizePolicy();
+ policy.setVerticalPolicy(verticalPolicy);
+ treeWidget->setSizePolicy(policy);
+ }
+};
+
+void tst_QWizard::task183550_stretchFactor()
+{
+ QWizard wizard;
+ WizardPage_task183550 *page1 = new WizardPage_task183550;
+ WizardPage_task183550 *page2 = new WizardPage_task183550;
+ wizard.addPage(page1);
+ wizard.addPage(page2);
+ wizard.resize(500, 2 * page2->treeWidgetSizeHintHeight());
+ wizard.show();
+
+ QCOMPARE(wizard.currentPage(), static_cast<QWizardPage*>(page1));
+
+ // ----
+ page2->disableVerticalExpansion();
+ wizard.next();
+ QCOMPARE(wizard.currentPage(), static_cast<QWizardPage*>(page2));
+ QVERIFY(page2->treeWidgetHeight() == page2->treeWidgetSizeHintHeight());
+
+ wizard.back();
+ QCOMPARE(wizard.currentPage(), static_cast<QWizardPage*>(page1));
+
+ // ----
+ page2->enableVerticalExpansion();
+ wizard.next();
+ QCOMPARE(wizard.currentPage(), static_cast<QWizardPage*>(page2));
+ QVERIFY(page2->treeWidgetHeight() > page2->treeWidgetSizeHintHeight());
+
+ wizard.back();
+ QCOMPARE(wizard.currentPage(), static_cast<QWizardPage*>(page1));
+
+ // ----
+ page2->disableVerticalExpansion();
+ wizard.next();
+ QCOMPARE(wizard.currentPage(), static_cast<QWizardPage*>(page2));
+ QVERIFY(page2->treeWidgetHeight() == page2->treeWidgetSizeHintHeight());
+}
+
+void tst_QWizard::task161658_alignments()
+{
+ QWizard wizard;
+ wizard.setWizardStyle(QWizard::MacStyle);
+
+ QWizardPage page;
+ page.setTitle("Title");
+ page.setSubTitle("SUBTITLE#: The subtitle bust be alligned with the rest of the widget");
+
+ QLabel label1("Field:");
+ QLineEdit lineEdit1;
+ QGridLayout *layout = new QGridLayout;
+ layout->addWidget(&label1, 0, 0);
+ layout->addWidget(&lineEdit1, 0, 1);
+ page.setLayout(layout);
+
+ int idx = wizard.addPage(&page);
+ wizard.setStartId(idx);
+ wizard.show();
+ QTest::qWait(100);
+
+ foreach (QLabel *subtitleLabel, qFindChildren<QLabel *>(&wizard)) {
+ if (subtitleLabel->text().startsWith("SUBTITLE#")) {
+ QCOMPARE(lineEdit1.mapToGlobal(lineEdit1.contentsRect().bottomRight()).x(),
+ subtitleLabel->mapToGlobal(subtitleLabel->contentsRect().bottomRight()).x());
+ return;
+ }
+ }
+ QFAIL("Subtitle label not found");
+}
+
+void tst_QWizard::task177022_setFixedSize()
+{
+ int width = 300;
+ int height = 200;
+ QWizard wiz;
+ QWizardPage page1;
+ QWizardPage page2;
+ int page1_id = wiz.addPage(&page1);
+ int page2_id = wiz.addPage(&page2);
+ wiz.setFixedSize(width, height);
+ if (wiz.wizardStyle() == QWizard::AeroStyle)
+ QEXPECT_FAIL("", "this probably relates to non-client area hack for AeroStyle titlebar "
+ "effect; not sure if it qualifies as a bug or not", Continue);
+ QCOMPARE(wiz.size(), QSize(width, height));
+ QCOMPARE(wiz.minimumWidth(), width);
+ QCOMPARE(wiz.minimumHeight(), height);
+ QCOMPARE(wiz.maximumWidth(), width);
+ QCOMPARE(wiz.maximumHeight(), height);
+
+ wiz.show();
+ QTest::qWait(100);
+ QCOMPARE(wiz.size(), QSize(width, height));
+ QCOMPARE(wiz.minimumWidth(), width);
+ QCOMPARE(wiz.minimumHeight(), height);
+ QCOMPARE(wiz.maximumWidth(), width);
+ QCOMPARE(wiz.maximumHeight(), height);
+
+ wiz.next();
+ QTest::qWait(100);
+ QCOMPARE(wiz.size(), QSize(width, height));
+ QCOMPARE(wiz.minimumWidth(), width);
+ QCOMPARE(wiz.minimumHeight(), height);
+ QCOMPARE(wiz.maximumWidth(), width);
+ QCOMPARE(wiz.maximumHeight(), height);
+
+ wiz.removePage(page1_id);
+ wiz.removePage(page2_id);
+}
+
+void tst_QWizard::task248107_backButton()
+{
+ QWizard wizard;
+ QWizardPage page1;
+ QWizardPage page2;
+ QWizardPage page3;
+ QWizardPage page4;
+ wizard.addPage(&page1);
+ wizard.addPage(&page2);
+ wizard.addPage(&page3);
+ wizard.addPage(&page4);
+
+ wizard.show();
+ QTest::qWait(100);
+ QCOMPARE(wizard.currentPage(), &page1);
+
+ QTest::mouseClick(wizard.button(QWizard::NextButton), Qt::LeftButton);
+ QCOMPARE(wizard.currentPage(), &page2);
+
+ QTest::mouseClick(wizard.button(QWizard::NextButton), Qt::LeftButton);
+ QCOMPARE(wizard.currentPage(), &page3);
+
+ QTest::mouseClick(wizard.button(QWizard::NextButton), Qt::LeftButton);
+ QCOMPARE(wizard.currentPage(), &page4);
+
+ QTest::mouseClick(wizard.button(QWizard::BackButton), Qt::LeftButton);
+ QCOMPARE(wizard.currentPage(), &page3);
+
+ QTest::mouseClick(wizard.button(QWizard::BackButton), Qt::LeftButton);
+ QCOMPARE(wizard.currentPage(), &page2);
+
+ QTest::mouseClick(wizard.button(QWizard::BackButton), Qt::LeftButton);
+ QCOMPARE(wizard.currentPage(), &page1);
+}
+
+class WizardPage_task255350 : public QWizardPage
+{
+public:
+ QLineEdit *lineEdit;
+ WizardPage_task255350()
+ : lineEdit(new QLineEdit)
+ {
+ registerField("dummy*", lineEdit);
+ }
+};
+
+void tst_QWizard::task255350_fieldObjectDestroyed()
+{
+ QWizard wizard;
+ WizardPage_task255350 *page = new WizardPage_task255350;
+ int id = wizard.addPage(page);
+ delete page->lineEdit;
+ wizard.removePage(id); // don't crash!
+ delete page;
+}
+
+QTEST_MAIN(tst_QWizard)
+#include "tst_qwizard.moc"
diff --git a/tests/auto/widgets/effects/effects.pro b/tests/auto/widgets/effects/effects.pro
new file mode 100644
index 0000000000..fab24d6296
--- /dev/null
+++ b/tests/auto/widgets/effects/effects.pro
@@ -0,0 +1,4 @@
+TEMPLATE=subdirs
+SUBDIRS=\
+ qgraphicseffect \
+
diff --git a/tests/auto/widgets/effects/qgraphicseffect/qgraphicseffect.pro b/tests/auto/widgets/effects/qgraphicseffect/qgraphicseffect.pro
new file mode 100644
index 0000000000..171ab3ffda
--- /dev/null
+++ b/tests/auto/widgets/effects/qgraphicseffect/qgraphicseffect.pro
@@ -0,0 +1,7 @@
+load(qttest_p4)
+
+QT += widgets widgets-private
+QT += core-private gui-private
+
+SOURCES += tst_qgraphicseffect.cpp
+CONFIG += parallel_test
diff --git a/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp b/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp
new file mode 100644
index 0000000000..2d9d87a2c5
--- /dev/null
+++ b/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp
@@ -0,0 +1,760 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include <QtWidgets/qdesktopwidget.h>
+#include <QtWidgets/qgraphicseffect.h>
+#include <QtWidgets/qgraphicsview.h>
+#include <QtWidgets/qgraphicsscene.h>
+#include <QtWidgets/qgraphicsitem.h>
+#include <QtWidgets/qgraphicswidget.h>
+#include <QtWidgets/qstyleoption.h>
+
+#include <private/qgraphicseffect_p.h>
+#include "../../../platformquirks.h"
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QGraphicsEffect : public QObject
+{
+ Q_OBJECT
+public slots:
+ void initTestCase();
+
+private slots:
+ void setEnabled();
+ void source();
+ void boundingRectFor();
+ void boundingRect();
+ void boundingRect2();
+ void draw();
+ void opacity();
+ void grayscale();
+ void colorize();
+ void drawPixmapItem();
+ void deviceCoordinateTranslateCaching();
+ void inheritOpacity();
+ void dropShadowClipping();
+ void childrenVisibilityShouldInvalidateCache();
+ void prepareGeometryChangeInvalidateCache();
+ void itemHasNoContents();
+};
+
+void tst_QGraphicsEffect::initTestCase()
+{}
+
+class CustomItem : public QGraphicsRectItem
+{
+public:
+ CustomItem(qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent = 0)
+ : QGraphicsRectItem(x, y, width, height, parent), numRepaints(0),
+ m_painter(0), m_styleOption(0)
+ {}
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+ {
+ m_painter = painter;
+ m_styleOption = option;
+ ++numRepaints;
+ QGraphicsRectItem::paint(painter, option, widget);
+ }
+
+ void reset()
+ {
+ numRepaints = 0;
+ m_painter = 0;
+ m_styleOption = 0;
+ }
+
+ int numRepaints;
+ QPainter *m_painter;
+ const QStyleOption *m_styleOption;
+};
+
+class CustomEffect : public QGraphicsEffect
+{
+public:
+ CustomEffect()
+ : QGraphicsEffect(), numRepaints(0), m_margin(10),
+ doNothingInDraw(false), m_painter(0), m_styleOption(0), m_source(0), m_opacity(1.0)
+ {}
+
+ QRectF boundingRectFor(const QRectF &rect) const
+ { return rect.adjusted(-m_margin, -m_margin, m_margin, m_margin); }
+
+ void reset()
+ {
+ numRepaints = 0;
+ m_sourceChangedFlags = QGraphicsEffect::ChangeFlags();
+ m_painter = 0;
+ m_styleOption = 0;
+ m_source = 0;
+ m_opacity = 1.0;
+ }
+
+ void setMargin(int margin)
+ {
+ m_margin = margin;
+ updateBoundingRect();
+ }
+
+ int margin() const
+ { return m_margin; }
+
+ void draw(QPainter *painter)
+ {
+ ++numRepaints;
+ if (doNothingInDraw)
+ return;
+ m_source = source();
+ m_painter = painter;
+ m_styleOption = source()->styleOption();
+ m_opacity = painter->opacity();
+ drawSource(painter);
+ }
+
+ void sourceChanged(QGraphicsEffect::ChangeFlags flags)
+ { m_sourceChangedFlags |= flags; }
+
+ int numRepaints;
+ int m_margin;
+ QGraphicsEffect::ChangeFlags m_sourceChangedFlags;
+ bool doNothingInDraw;
+ QPainter *m_painter;
+ const QStyleOption *m_styleOption;
+ QGraphicsEffectSource *m_source;
+ qreal m_opacity;
+};
+
+void tst_QGraphicsEffect::setEnabled()
+{
+ CustomEffect effect;
+ QVERIFY(effect.isEnabled());
+
+ effect.setEnabled(false);
+ QVERIFY(!effect.isEnabled());
+}
+
+void tst_QGraphicsEffect::source()
+{
+ QPointer<CustomEffect> effect = new CustomEffect;
+ QVERIFY(!effect->source());
+ QVERIFY(!effect->m_sourceChangedFlags);
+
+ // Install effect on QGraphicsItem.
+ QGraphicsItem *item = new QGraphicsRectItem(0, 0, 10, 10);
+ item->setGraphicsEffect(effect);
+ QVERIFY(effect->source());
+ QCOMPARE(effect->source()->graphicsItem(), (const QGraphicsItem*)item);
+ QVERIFY(effect->m_sourceChangedFlags & QGraphicsEffect::SourceAttached);
+ effect->reset();
+
+ // Make sure disabling/enabling the effect doesn't change the source.
+ effect->setEnabled(false);
+ QVERIFY(effect->source());
+ QCOMPARE(effect->source()->graphicsItem(), (const QGraphicsItem*)item);
+ QVERIFY(!effect->m_sourceChangedFlags);
+ effect->reset();
+
+ effect->setEnabled(true);
+ QVERIFY(effect->source());
+ QCOMPARE(effect->source()->graphicsItem(), (const QGraphicsItem*)item);
+ QVERIFY(!effect->m_sourceChangedFlags);
+ effect->reset();
+
+ // Uninstall effect on QGraphicsItem.
+ effect->reset();
+ item->setGraphicsEffect(0);
+ QVERIFY(!effect);
+ effect = new CustomEffect;
+
+ // The item takes ownership and should delete the effect when destroyed.
+ item->setGraphicsEffect(effect);
+ QPointer<QGraphicsEffectSource> source = effect->source();
+ QVERIFY(source);
+ QCOMPARE(source->graphicsItem(), (const QGraphicsItem*)item);
+ delete item;
+ QVERIFY(!effect);
+ QVERIFY(!source);
+}
+
+void tst_QGraphicsEffect::boundingRectFor()
+{
+ CustomEffect effect;
+ int margin = effect.margin();
+ const QRectF source(0, 0, 100, 100);
+ QCOMPARE(effect.boundingRectFor(source), source.adjusted(-margin, -margin, margin, margin));
+
+ effect.setMargin(margin = 20);
+ QCOMPARE(effect.boundingRectFor(source), source.adjusted(-margin, -margin, margin, margin));
+}
+
+void tst_QGraphicsEffect::boundingRect()
+{
+ // No source; empty bounding rect.
+ CustomEffect *effect = new CustomEffect;
+ QCOMPARE(effect->boundingRect(), QRectF());
+
+ // Install effect on QGraphicsItem.
+ QRectF itemRect(0, 0, 100, 100);
+ QGraphicsRectItem *item = new QGraphicsRectItem;
+ item->setRect(itemRect);
+ item->setGraphicsEffect(effect);
+ int margin = effect->margin();
+ QCOMPARE(effect->boundingRect(), itemRect.adjusted(-margin, -margin, margin, margin));
+ QCOMPARE(effect->boundingRect(), effect->boundingRectFor(itemRect));
+
+ // Make sure disabling/enabling the effect doesn't change the bounding rect.
+ effect->setEnabled(false);
+ QCOMPARE(effect->boundingRect(), itemRect.adjusted(-margin, -margin, margin, margin));
+ QCOMPARE(effect->boundingRect(), effect->boundingRectFor(itemRect));
+ effect->setEnabled(true);
+ QCOMPARE(effect->boundingRect(), itemRect.adjusted(-margin, -margin, margin, margin));
+ QCOMPARE(effect->boundingRect(), effect->boundingRectFor(itemRect));
+
+ // Change effect margins.
+ effect->setMargin(margin = 20);
+ QCOMPARE(effect->boundingRect(), itemRect.adjusted(-margin, -margin, margin, margin));
+ QCOMPARE(effect->boundingRect(), effect->boundingRectFor(itemRect));
+
+ // Uninstall effect on QGraphicsItem.
+ QPointer<CustomEffect> ptr = effect;
+ item->setGraphicsEffect(0);
+ QVERIFY(!ptr);
+
+ delete item;
+}
+
+void tst_QGraphicsEffect::boundingRect2()
+{
+ CustomEffect *effect = new CustomEffect;
+ QGraphicsRectItem *root = new QGraphicsRectItem;
+ root->setGraphicsEffect(effect);
+
+ QGraphicsRectItem *child = new QGraphicsRectItem;
+ QRectF childRect(0, 0, 100, 100);
+ child->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
+ child->setRect(childRect);
+ child->setParentItem(root);
+
+ QGraphicsRectItem *grandChild = new QGraphicsRectItem;
+ QRectF grandChildRect(0, 0, 200, 200);
+ grandChild->setRect(grandChildRect);
+ grandChild->setParentItem(child);
+
+ // Make sure the effect's bounding rect is clipped to the child's bounding rect.
+ QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect));
+
+ // Disable ItemClipsChildrenToShape; effect's bounding rect is no longer clipped.
+ child->setFlag(QGraphicsItem::ItemClipsChildrenToShape, false);
+ QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect | grandChildRect));
+
+ // Add root item to a scene, do the same tests as above. Results should be the same.
+ QGraphicsScene scene;
+ scene.addItem(root);
+
+ child->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
+ QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect));
+
+ child->setFlag(QGraphicsItem::ItemClipsChildrenToShape, false);
+ QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect | grandChildRect));
+
+ // Now add the scene to a view, results should be the same.
+ QGraphicsView view(&scene);
+
+ child->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
+ QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect));
+
+ child->setFlag(QGraphicsItem::ItemClipsChildrenToShape, false);
+ QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect | grandChildRect));
+
+ CustomEffect *childEffect = new CustomEffect;
+ child->setGraphicsEffect(childEffect);
+ QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childEffect->boundingRectFor(childRect | grandChildRect)));
+
+ child->setGraphicsEffect(0);
+ QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect | grandChildRect));
+}
+
+void tst_QGraphicsEffect::draw()
+{
+ QGraphicsScene scene;
+ CustomItem *item = new CustomItem(0, 0, 100, 100);
+ scene.addItem(item);
+
+ QGraphicsView view(&scene);
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+ QTRY_VERIFY(item->numRepaints > 0);
+ item->reset();
+
+ // Make sure installing the effect triggers a repaint.
+ CustomEffect *effect = new CustomEffect;
+ item->setGraphicsEffect(effect);
+ QTRY_COMPARE(effect->numRepaints, 1);
+ QTRY_COMPARE(item->numRepaints, 1);
+
+ // Make sure QPainter* and QStyleOptionGraphicsItem* stays persistent
+ // during QGraphicsEffect::draw/QGraphicsItem::paint.
+ QVERIFY(effect->m_painter);
+ QCOMPARE(effect->m_painter, item->m_painter);
+ QCOMPARE(effect->m_styleOption, item->m_styleOption);
+ // Make sure QGraphicsEffect::source is persistent.
+ QCOMPARE(effect->m_source, effect->source());
+ effect->reset();
+ item->reset();
+
+ // Make sure updating the source triggers a repaint.
+ item->update();
+ QTRY_COMPARE(effect->numRepaints, 1);
+ QTRY_COMPARE(item->numRepaints, 1);
+ QVERIFY(effect->m_sourceChangedFlags & QGraphicsEffect::SourceInvalidated);
+ effect->reset();
+ item->reset();
+
+ // Make sure changing the effect's bounding rect triggers a repaint.
+ effect->setMargin(20);
+ QTRY_COMPARE(effect->numRepaints, 1);
+ QTRY_COMPARE(item->numRepaints, 1);
+ effect->reset();
+ item->reset();
+
+ // Make sure change the item's bounding rect triggers a repaint.
+ item->setRect(0, 0, 50, 50);
+ QTRY_COMPARE(effect->numRepaints, 1);
+ QTRY_COMPARE(item->numRepaints, 1);
+ QVERIFY(effect->m_sourceChangedFlags & QGraphicsEffect::SourceBoundingRectChanged);
+ effect->reset();
+ item->reset();
+
+ // Make sure the effect is the one to issue a repaint of the item.
+ effect->doNothingInDraw = true;
+ item->update();
+ QTRY_COMPARE(effect->numRepaints, 1);
+ QCOMPARE(item->numRepaints, 0);
+ effect->doNothingInDraw = false;
+ effect->reset();
+ item->reset();
+
+ // Make sure we update the source when disabling/enabling the effect.
+ effect->setEnabled(false);
+ QTest::qWait(50);
+ QCOMPARE(effect->numRepaints, 0);
+ QCOMPARE(item->numRepaints, 1);
+ effect->reset();
+ item->reset();
+
+ effect->setEnabled(true);
+ QTRY_COMPARE(effect->numRepaints, 1);
+ QTRY_COMPARE(item->numRepaints, 1);
+ effect->reset();
+ item->reset();
+
+ // Effect is already enabled; nothing should happen.
+ effect->setEnabled(true);
+ QTest::qWait(50);
+ QCOMPARE(effect->numRepaints, 0);
+ QCOMPARE(item->numRepaints, 0);
+
+ // Make sure uninstalling an effect triggers a repaint.
+ QPointer<CustomEffect> ptr = effect;
+ item->setGraphicsEffect(0);
+ QVERIFY(!ptr);
+ QTRY_COMPARE(item->numRepaints, 1);
+}
+
+void tst_QGraphicsEffect::opacity()
+{
+ // Make sure the painter's opacity is correct in QGraphicsEffect::draw.
+ QGraphicsScene scene;
+ CustomItem *item = new CustomItem(0, 0, 100, 100);
+ item->setOpacity(0.5);
+ CustomEffect *effect = new CustomEffect;
+ item->setGraphicsEffect(effect);
+ scene.addItem(item);
+
+ QGraphicsView view(&scene);
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+ QTRY_VERIFY(effect->numRepaints > 0);
+ QCOMPARE(effect->m_opacity, qreal(0.5));
+}
+
+void tst_QGraphicsEffect::grayscale()
+{
+ if (qApp->desktop()->depth() < 24)
+ QSKIP("Test only works on 32 bit displays", SkipAll);
+
+ QGraphicsScene scene(0, 0, 100, 100);
+
+ QGraphicsRectItem *item = scene.addRect(0, 0, 50, 50);
+ item->setPen(Qt::NoPen);
+ item->setBrush(QColor(122, 193, 66)); // Qt light green
+
+ QGraphicsColorizeEffect *effect = new QGraphicsColorizeEffect;
+ effect->setColor(Qt::black);
+ item->setGraphicsEffect(effect);
+
+ QPainter painter;
+ QImage image(100, 100, QImage::Format_ARGB32_Premultiplied);
+
+ image.fill(0);
+ painter.begin(&image);
+ painter.setRenderHint(QPainter::Antialiasing);
+ scene.render(&painter);
+ painter.end();
+
+ QCOMPARE(image.pixel(10, 10), qRgb(148, 148, 148));
+
+ effect->setStrength(0.5);
+
+ image.fill(0);
+ painter.begin(&image);
+ painter.setRenderHint(QPainter::Antialiasing);
+ scene.render(&painter);
+ painter.end();
+
+ QCOMPARE(image.pixel(10, 10), qRgb(135, 171, 107));
+
+ effect->setStrength(0.0);
+
+ image.fill(0);
+ painter.begin(&image);
+ painter.setRenderHint(QPainter::Antialiasing);
+ scene.render(&painter);
+ painter.end();
+
+ QCOMPARE(image.pixel(10, 10), qRgb(122, 193, 66));
+}
+
+void tst_QGraphicsEffect::colorize()
+{
+ if (qApp->desktop()->depth() < 24)
+ QSKIP("Test only works on 32 bit displays", SkipAll);
+
+ QGraphicsScene scene(0, 0, 100, 100);
+
+ QGraphicsRectItem *item = scene.addRect(0, 0, 50, 50);
+ item->setPen(Qt::NoPen);
+ item->setBrush(QColor(122, 193, 66)); // Qt light green
+
+ QGraphicsColorizeEffect *effect = new QGraphicsColorizeEffect;
+ effect->setColor(QColor(102, 153, 51)); // Qt dark green
+ item->setGraphicsEffect(effect);
+
+ QPainter painter;
+ QImage image(100, 100, QImage::Format_ARGB32_Premultiplied);
+
+ image.fill(0);
+ painter.begin(&image);
+ painter.setRenderHint(QPainter::Antialiasing);
+ scene.render(&painter);
+ painter.end();
+
+ QCOMPARE(image.pixel(10, 10), qRgb(191, 212, 169));
+
+ effect->setStrength(0.5);
+
+ image.fill(0);
+ painter.begin(&image);
+ painter.setRenderHint(QPainter::Antialiasing);
+ scene.render(&painter);
+ painter.end();
+
+ QCOMPARE(image.pixel(10, 10), qRgb(156, 203, 117));
+
+ effect->setStrength(0.0);
+
+ image.fill(0);
+ painter.begin(&image);
+ painter.setRenderHint(QPainter::Antialiasing);
+ scene.render(&painter);
+ painter.end();
+
+ QCOMPARE(image.pixel(10, 10), qRgb(122, 193, 66));
+}
+
+class PixmapItemEffect : public QGraphicsEffect
+{
+public:
+ PixmapItemEffect(const QPixmap &source)
+ : QGraphicsEffect()
+ , pixmap(source)
+ , repaints(0)
+ {}
+
+ QRectF boundingRectFor(const QRectF &rect) const
+ { return rect; }
+
+ void draw(QPainter *painter)
+ {
+ QVERIFY(sourcePixmap(Qt::LogicalCoordinates).handle() == pixmap.handle());
+ QVERIFY((painter->worldTransform().type() <= QTransform::TxTranslate) == (sourcePixmap(Qt::DeviceCoordinates).handle() == pixmap.handle()));
+
+ ++repaints;
+ }
+ QPixmap pixmap;
+ int repaints;
+};
+
+void tst_QGraphicsEffect::drawPixmapItem()
+{
+ QImage image(32, 32, QImage::Format_RGB32);
+ QPainter p(&image);
+ p.fillRect(0, 0, 32, 16, Qt::blue);
+ p.fillRect(0, 16, 32, 16, Qt::red);
+ p.end();
+
+ QGraphicsScene scene;
+ QGraphicsPixmapItem *item = new QGraphicsPixmapItem(QPixmap::fromImage(image));
+ scene.addItem(item);
+
+ PixmapItemEffect *effect = new PixmapItemEffect(item->pixmap());
+ item->setGraphicsEffect(effect);
+
+ QGraphicsView view(&scene);
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+ QTRY_VERIFY(effect->repaints >= 1);
+
+ item->rotate(180);
+
+ QTRY_VERIFY(effect->repaints >= 2);
+}
+
+class DeviceEffect : public QGraphicsEffect
+{
+public:
+ QRectF boundingRectFor(const QRectF &rect) const
+ { return rect; }
+
+ void draw(QPainter *painter)
+ {
+ QPoint offset;
+ QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset, QGraphicsEffect::NoPad);
+
+ if (pixmap.isNull())
+ return;
+
+ painter->save();
+ painter->setWorldTransform(QTransform());
+ painter->drawPixmap(offset, pixmap);
+ painter->restore();
+ }
+};
+
+void tst_QGraphicsEffect::deviceCoordinateTranslateCaching()
+{
+ QGraphicsScene scene;
+ CustomItem *item = new CustomItem(0, 0, 10, 10);
+ scene.addItem(item);
+ scene.setSceneRect(0, 0, 50, 0);
+
+ item->setGraphicsEffect(new DeviceEffect);
+ item->setPen(Qt::NoPen);
+ item->setBrush(Qt::red);
+
+ QGraphicsView view(&scene);
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+
+ QTRY_VERIFY(item->numRepaints >= 1);
+ int numRepaints = item->numRepaints;
+
+ item->translate(10, 0);
+
+ QTRY_VERIFY(item->numRepaints == numRepaints);
+}
+
+void tst_QGraphicsEffect::inheritOpacity()
+{
+ QGraphicsScene scene;
+ QGraphicsRectItem *rectItem = new QGraphicsRectItem(0, 0, 10, 10);
+ CustomItem *item = new CustomItem(0, 0, 10, 10, rectItem);
+
+ scene.addItem(rectItem);
+
+ item->setGraphicsEffect(new DeviceEffect);
+ item->setPen(Qt::NoPen);
+ item->setBrush(Qt::red);
+
+ rectItem->setOpacity(0.5);
+
+ QGraphicsView view(&scene);
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+
+ QTRY_VERIFY(item->numRepaints >= 1);
+
+ int numRepaints = item->numRepaints;
+
+ rectItem->setOpacity(1);
+
+ // item should have been rerendered due to opacity changing
+ QTRY_VERIFY(item->numRepaints > numRepaints);
+}
+
+void tst_QGraphicsEffect::dropShadowClipping()
+{
+ QImage img(128, 128, QImage::Format_ARGB32_Premultiplied);
+ img.fill(0xffffffff);
+
+ QGraphicsScene scene;
+ QGraphicsRectItem *item = new QGraphicsRectItem(-5, -500, 10, 1000);
+ item->setGraphicsEffect(new QGraphicsDropShadowEffect);
+ item->setPen(Qt::NoPen);
+ item->setBrush(Qt::red);
+
+ scene.addItem(item);
+
+ QPainter p(&img);
+ scene.render(&p, img.rect(), QRect(-64, -64, 128, 128));
+ p.end();
+
+ for (int y = 1; y < img.height(); ++y)
+ for (int x = 0; x < img.width(); ++x)
+ QCOMPARE(img.pixel(x, y), img.pixel(x, y-1));
+}
+
+class MyGraphicsItem : public QGraphicsWidget
+{
+public:
+ MyGraphicsItem(QGraphicsItem *parent = 0) :
+ QGraphicsWidget(parent), nbPaint(0)
+ {}
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+ {
+ nbPaint++;
+ QGraphicsWidget::paint(painter, option, widget);
+ }
+ int nbPaint;
+};
+
+void tst_QGraphicsEffect::childrenVisibilityShouldInvalidateCache()
+{
+ QGraphicsScene scene;
+ MyGraphicsItem parent;
+ parent.resize(200, 200);
+ QGraphicsWidget child(&parent);
+ child.resize(200, 200);
+ child.setVisible(false);
+ scene.addItem(&parent);
+ QGraphicsView view(&scene);
+ view.show();
+ QApplication::setActiveWindow(&view);
+ QTest::qWaitForWindowShown(&view);
+ QTRY_VERIFY(parent.nbPaint >= 1);
+ //we set an effect on the parent
+ parent.setGraphicsEffect(new QGraphicsDropShadowEffect(&parent));
+ //flush the events
+ QApplication::processEvents();
+ //new effect applied->repaint
+ QVERIFY(parent.nbPaint >= 2);
+ child.setVisible(true);
+ //flush the events
+ QApplication::processEvents();
+ //a new child appears we need to redraw the effect.
+ QVERIFY(parent.nbPaint >= 3);
+}
+
+void tst_QGraphicsEffect::prepareGeometryChangeInvalidateCache()
+{
+ MyGraphicsItem *item = new MyGraphicsItem;
+ item->resize(200, 200);
+
+ QGraphicsScene scene;
+ scene.addItem(item);
+
+ QGraphicsView view(&scene);
+ if(PlatformQuirks::isAutoMaximizing())
+ view.showFullScreen();
+ else
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+ QTRY_VERIFY(item->nbPaint >= 1);
+
+ item->nbPaint = 0;
+ item->setGraphicsEffect(new QGraphicsDropShadowEffect);
+ QTRY_COMPARE(item->nbPaint, 1);
+
+ item->nbPaint = 0;
+ item->resize(300, 300);
+ QTRY_COMPARE(item->nbPaint, 1);
+
+ item->nbPaint = 0;
+ item->setPos(item->pos() + QPointF(10, 10));
+ QTest::qWait(50);
+ QCOMPARE(item->nbPaint, 0);
+}
+
+void tst_QGraphicsEffect::itemHasNoContents()
+{
+ QGraphicsRectItem *parent = new QGraphicsRectItem;
+ parent->setFlag(QGraphicsItem::ItemHasNoContents);
+
+ MyGraphicsItem *child = new MyGraphicsItem;
+ child->setParentItem(parent);
+ child->resize(200, 200);
+
+ QGraphicsScene scene;
+ scene.addItem(parent);
+
+ QGraphicsView view(&scene);
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+ QTRY_VERIFY(child->nbPaint >= 1);
+
+ CustomEffect *effect = new CustomEffect;
+ parent->setGraphicsEffect(effect);
+ QTRY_COMPARE(effect->numRepaints, 1);
+
+ for (int i = 0; i < 3; ++i) {
+ effect->reset();
+ effect->update();
+ QTRY_COMPARE(effect->numRepaints, 1);
+ }
+}
+
+QTEST_MAIN(tst_QGraphicsEffect)
+#include "tst_qgraphicseffect.moc"
+
diff --git a/tests/auto/widgets/graphicsview/graphicsview.pro b/tests/auto/widgets/graphicsview/graphicsview.pro
new file mode 100644
index 0000000000..9955e45b64
--- /dev/null
+++ b/tests/auto/widgets/graphicsview/graphicsview.pro
@@ -0,0 +1,32 @@
+TEMPLATE=subdirs
+SUBDIRS=\
+ qgraphicsanchorlayout \
+ qgraphicsanchorlayout1 \
+ qgraphicseffectsource \
+ qgraphicsgridlayout \
+ qgraphicsitem \
+ qgraphicsitemanimation \
+ qgraphicslayout \
+ qgraphicslayoutitem \
+ qgraphicslinearlayout \
+ qgraphicsobject \
+ qgraphicspixmapitem \
+ qgraphicspolygonitem \
+ qgraphicsproxywidget \
+ qgraphicsscene \
+ qgraphicssceneindex \
+ qgraphicstransform \
+ qgraphicsview \
+ qgraphicswidget \
+
+!contains(QT_CONFIG, private_tests): SUBDIRS -= \
+ qgraphicsanchorlayout \
+ qgraphicsanchorlayout1 \
+ qgraphicsitem \
+ qgraphicsscene \
+ qgraphicssceneindex \
+
+# These tests require the cleanlooks style
+!contains(styles, cleanlooks):SUBDIRS -= \
+ qgraphicsproxywidget \
+ qgraphicswidget \
diff --git a/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/qgraphicsanchorlayout.pro b/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/qgraphicsanchorlayout.pro
new file mode 100644
index 0000000000..5aa2936e3e
--- /dev/null
+++ b/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/qgraphicsanchorlayout.pro
@@ -0,0 +1,5 @@
+load(qttest_p4)
+QT += widgets widgets-private
+QT += core-private gui-private
+SOURCES += tst_qgraphicsanchorlayout.cpp
+CONFIG += parallel_test
diff --git a/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp
new file mode 100644
index 0000000000..5dbe501ea8
--- /dev/null
+++ b/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp
@@ -0,0 +1,2091 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QtWidgets/qgraphicsanchorlayout.h>
+#include <private/qgraphicsanchorlayout_p.h>
+#include <QtWidgets/qgraphicswidget.h>
+#include <QtWidgets/qgraphicsproxywidget.h>
+#include <QtWidgets/qgraphicsview.h>
+#include <QtWidgets/qwindowsstyle.h>
+
+
+class tst_QGraphicsAnchorLayout : public QObject {
+ Q_OBJECT
+
+public:
+ tst_QGraphicsAnchorLayout() : QObject() {
+ hasSimplification = qgetenv("QT_ANCHORLAYOUT_NO_SIMPLIFICATION").isEmpty();
+ }
+
+private:
+ bool hasSimplification;
+
+private slots:
+ void simple();
+ void simple_center();
+ void simple_semifloat();
+ void layoutDirection();
+ void diagonal();
+ void parallel();
+ void parallel2();
+ void snake();
+ void snakeOppositeDirections();
+ void fairDistribution();
+ void fairDistributionOppositeDirections();
+ void proportionalPreferred();
+ void example();
+ void setSpacing();
+ void styleDefaults();
+ void hardComplexS60();
+ void stability();
+ void delete_anchor();
+ void conflicts();
+ void sizePolicy();
+ void floatConflict();
+ void infiniteMaxSizes();
+ void simplifiableUnfeasible();
+ void simplificationVsOrder();
+ void parallelSimplificationOfCenter();
+ void simplificationVsRedundance();
+ void spacingPersistency();
+ void snakeParallelWithLayout();
+ void parallelToHalfLayout();
+ void globalSpacing();
+ void graphicsAnchorHandling();
+ void invalidHierarchyCheck();
+};
+
+class RectWidget : public QGraphicsWidget
+{
+public:
+ RectWidget(QGraphicsItem *parent = 0) : QGraphicsWidget(parent){}
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+ {
+ Q_UNUSED(option);
+ Q_UNUSED(widget);
+ painter->drawRoundRect(rect());
+ painter->drawLine(rect().topLeft(), rect().bottomRight());
+ painter->drawLine(rect().bottomLeft(), rect().topRight());
+ }
+};
+
+static QGraphicsWidget *createItem(const QSizeF &minimum = QSizeF(100.0, 100.0),
+ const QSizeF &preferred = QSize(150.0, 100.0),
+ const QSizeF &maximum = QSizeF(200.0, 100.0),
+ const QString &name = QString())
+{
+ QGraphicsWidget *w = new RectWidget;
+ w->setMinimumSize(minimum);
+ w->setPreferredSize(preferred);
+ w->setMaximumSize(maximum);
+ w->setData(0, name);
+ return w;
+}
+
+static void setAnchor(QGraphicsAnchorLayout *l,
+ QGraphicsLayoutItem *firstItem,
+ Qt::AnchorPoint firstEdge,
+ QGraphicsLayoutItem *secondItem,
+ Qt::AnchorPoint secondEdge,
+ qreal spacing = 0)
+{
+ QGraphicsAnchor *anchor = l->addAnchor(firstItem, firstEdge, secondItem, secondEdge);
+ anchor->setSpacing(spacing);
+}
+
+static bool checkReverseDirection(QGraphicsWidget *widget)
+{
+ QGraphicsLayout *layout = widget->layout();
+ qreal left, top, right, bottom;
+ layout->getContentsMargins(&left, &top, &right, &bottom);
+ widget->setLayoutDirection(Qt::LeftToRight);
+ QApplication::processEvents();
+ const QRectF layoutGeometry = layout->geometry();
+ QMap<QGraphicsLayoutItem *, QRectF> geometries;
+ for (int i = 0; i < layout->count(); ++i) {
+ QGraphicsLayoutItem *item = layout->itemAt(i);
+ geometries.insert(item, item->geometry());
+ }
+ widget->setLayoutDirection(Qt::RightToLeft);
+ QApplication::processEvents();
+ layoutGeometry.adjusted(+right, +top, -left, -bottom);
+ for (int i = 0; i < layout->count(); ++i) {
+ QGraphicsLayoutItem *item = layout->itemAt(i);
+ const QRectF rightToLeftGeometry = item->geometry();
+ const QRectF leftToRightGeometry = geometries.value(item);
+ QRectF expectedGeometry = leftToRightGeometry;
+ expectedGeometry.moveRight(layoutGeometry.right() - leftToRightGeometry.left());
+ if (expectedGeometry != rightToLeftGeometry) {
+ qDebug() << "layout->geometry():" << layoutGeometry
+ << "expected:" << expectedGeometry
+ << "actual:" << rightToLeftGeometry;
+ return false;
+ }
+ }
+ return true;
+}
+
+static bool layoutHasConflict(QGraphicsAnchorLayout *l)
+{
+ return QGraphicsAnchorLayoutPrivate::get(l)->hasConflicts();
+}
+
+static bool usedSimplex(QGraphicsAnchorLayout *l, Qt::Orientation o)
+{
+ QGraphicsAnchorLayoutPrivate::Orientation oo = (o == Qt::Horizontal) ?
+ QGraphicsAnchorLayoutPrivate::Horizontal :
+ QGraphicsAnchorLayoutPrivate::Vertical;
+
+ return QGraphicsAnchorLayoutPrivate::get(l)->lastCalculationUsedSimplex[oo];
+}
+
+void tst_QGraphicsAnchorLayout::simple()
+{
+ QGraphicsWidget *w1 = createItem();
+ QGraphicsWidget *w2 = createItem();
+
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
+ l->setContentsMargins(0, 0, 0, 0);
+
+ // Horizontal
+ l->addAnchor(l, Qt::AnchorLeft, w1, Qt::AnchorLeft);
+ l->addAnchor(w1, Qt::AnchorRight, w2, Qt::AnchorLeft);
+ l->addAnchor(w2, Qt::AnchorRight, l, Qt::AnchorRight);
+
+ // Vertical
+ l->addAnchors(l, w1, Qt::Vertical);
+ l->addAnchors(l, w2, Qt::Vertical);
+
+ QCOMPARE(l->count(), 2);
+
+ QGraphicsWidget p;
+ p.setLayout(l);
+ p.adjustSize();
+
+ if (hasSimplification) {
+ QVERIFY(!usedSimplex(l, Qt::Horizontal));
+ QVERIFY(!usedSimplex(l, Qt::Vertical));
+ }
+}
+
+void tst_QGraphicsAnchorLayout::simple_center()
+{
+ QSizeF minSize(10, 10);
+ QSizeF pref(50, 10);
+ QSizeF maxSize(100, 10);
+
+ QGraphicsWidget *a = createItem(minSize, pref, maxSize, "a");
+ QGraphicsWidget *b = createItem(minSize, pref, maxSize, "b");
+ QGraphicsWidget *c = createItem(minSize, pref, maxSize, "c");
+
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
+ l->setContentsMargins(0, 0, 0, 0);
+ // horizontal
+ setAnchor(l, l, Qt::AnchorLeft, a, Qt::AnchorLeft, 0);
+ setAnchor(l, a, Qt::AnchorRight, b, Qt::AnchorLeft, 0);
+ setAnchor(l, b, Qt::AnchorRight, l, Qt::AnchorRight, 0);
+ setAnchor(l, a, Qt::AnchorHorizontalCenter, c, Qt::AnchorLeft, 0);
+ setAnchor(l, c, Qt::AnchorRight, b, Qt::AnchorHorizontalCenter, 0);
+
+ // vertical
+ setAnchor(l, l, Qt::AnchorTop, a, Qt::AnchorTop, 0);
+ setAnchor(l, l, Qt::AnchorTop, b, Qt::AnchorTop, 0);
+ setAnchor(l, a, Qt::AnchorBottom, c, Qt::AnchorTop, 0);
+ setAnchor(l, b, Qt::AnchorBottom, c, Qt::AnchorTop, 0);
+ setAnchor(l, c, Qt::AnchorBottom, l, Qt::AnchorBottom, 0);
+
+ QCOMPARE(l->count(), 3);
+
+ QGraphicsWidget *p = new QGraphicsWidget(0, Qt::Window);
+ p->setLayout(l);
+
+ QSizeF layoutMinimumSize = l->effectiveSizeHint(Qt::MinimumSize);
+ QCOMPARE(layoutMinimumSize, QSizeF(20, 20));
+
+ QSizeF layoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize);
+ QCOMPARE(layoutMaximumSize, QSizeF(200, 20));
+
+ if (hasSimplification) {
+ QVERIFY(usedSimplex(l, Qt::Horizontal));
+ QVERIFY(!usedSimplex(l, Qt::Vertical));
+ }
+
+ delete p;
+}
+
+void tst_QGraphicsAnchorLayout::simple_semifloat()
+{
+ // Useful for testing simplification between A_left and B_left.
+ // Unfortunately the only way to really test that now is to manually inspect the
+ // simplified graph.
+ QSizeF minSize(10, 10);
+ QSizeF pref(50, 10);
+ QSizeF maxSize(100, 10);
+
+ QGraphicsWidget *A = createItem(minSize, pref, maxSize, "A");
+ QGraphicsWidget *B = createItem(minSize, pref, maxSize, "B");
+ QGraphicsWidget *a = createItem(minSize, pref, maxSize, "a");
+ QGraphicsWidget *b = createItem(minSize, pref, maxSize, "b");
+
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
+ l->setContentsMargins(0, 0, 0, 0);
+
+ // horizontal
+ setAnchor(l, l, Qt::AnchorLeft, A, Qt::AnchorLeft, 0);
+ setAnchor(l, A, Qt::AnchorRight, B, Qt::AnchorLeft, 0);
+ setAnchor(l, B, Qt::AnchorRight, l, Qt::AnchorRight, 0);
+
+ setAnchor(l, A, Qt::AnchorLeft, a, Qt::AnchorLeft, 0);
+ setAnchor(l, B, Qt::AnchorLeft, b, Qt::AnchorLeft, 0);
+
+ // vertical
+ setAnchor(l, l, Qt::AnchorTop, A, Qt::AnchorTop, 0);
+ setAnchor(l, l, Qt::AnchorTop, B, Qt::AnchorTop, 0);
+ setAnchor(l, A, Qt::AnchorBottom, a, Qt::AnchorTop, 0);
+ setAnchor(l, B, Qt::AnchorBottom, b, Qt::AnchorTop, 0);
+ setAnchor(l, a, Qt::AnchorBottom, l, Qt::AnchorBottom, 0);
+ setAnchor(l, b, Qt::AnchorBottom, l, Qt::AnchorBottom, 0);
+
+ QCOMPARE(l->count(), 4);
+
+ QGraphicsWidget *p = new QGraphicsWidget(0, Qt::Window);
+ p->setLayout(l);
+
+ QSizeF layoutMinimumSize = l->effectiveSizeHint(Qt::MinimumSize);
+ QCOMPARE(layoutMinimumSize, QSizeF(20, 20));
+
+ QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(100, 20));
+
+ QSizeF layoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize);
+ QCOMPARE(layoutMaximumSize, QSizeF(200, 20));
+
+ delete p;
+}
+
+void tst_QGraphicsAnchorLayout::layoutDirection()
+{
+ QSizeF minSize(10, 10);
+ QSizeF pref(50, 10);
+ QSizeF maxSize(100, 10);
+
+ QGraphicsWidget *a = createItem(minSize, pref, maxSize, "a");
+ QGraphicsWidget *b = createItem(minSize, pref, maxSize, "b");
+ QGraphicsWidget *c = createItem(minSize, pref, QSizeF(100, 20), "c");
+
+ a->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+ b->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+ c->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+
+
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
+ l->setContentsMargins(0, 5, 10, 15);
+ // horizontal
+ setAnchor(l, l, Qt::AnchorLeft, a, Qt::AnchorLeft, 0);
+ setAnchor(l, a, Qt::AnchorRight, b, Qt::AnchorLeft, 0);
+ setAnchor(l, b, Qt::AnchorRight, l, Qt::AnchorRight, 0);
+ setAnchor(l, a, Qt::AnchorHorizontalCenter, c, Qt::AnchorLeft, 0);
+ setAnchor(l, c, Qt::AnchorRight, b, Qt::AnchorHorizontalCenter, 0);
+
+ // vertical
+ setAnchor(l, l, Qt::AnchorTop, a, Qt::AnchorTop, 0);
+ setAnchor(l, l, Qt::AnchorTop, b, Qt::AnchorTop, 0);
+ setAnchor(l, a, Qt::AnchorBottom, c, Qt::AnchorTop, 0);
+ setAnchor(l, b, Qt::AnchorBottom, c, Qt::AnchorTop, 0);
+ setAnchor(l, c, Qt::AnchorBottom, l, Qt::AnchorBottom, 0);
+
+ QCOMPARE(l->count(), 3);
+
+ QGraphicsWidget *p = new QGraphicsWidget(0, Qt::Window);
+ p->setLayoutDirection(Qt::LeftToRight);
+ p->setLayout(l);
+
+ QGraphicsScene scene;
+ QGraphicsView *view = new QGraphicsView(&scene);
+ scene.addItem(p);
+ p->show();
+ view->show();
+
+ QVERIFY(p->layout());
+ QCOMPARE(checkReverseDirection(p), true);
+
+ if (hasSimplification) {
+ QVERIFY(usedSimplex(l, Qt::Horizontal));
+ QVERIFY(!usedSimplex(l, Qt::Vertical));
+ }
+
+ delete p;
+ delete view;
+}
+
+void tst_QGraphicsAnchorLayout::diagonal()
+{
+ QSizeF minSize(10, 100);
+ QSizeF pref(70, 100);
+ QSizeF maxSize(100, 100);
+
+ QGraphicsWidget *a = createItem(minSize, pref, maxSize, "A");
+ QGraphicsWidget *b = createItem(minSize, pref, maxSize, "B");
+ QGraphicsWidget *c = createItem(minSize, pref, maxSize, "C");
+ QGraphicsWidget *d = createItem(minSize, pref, maxSize, "D");
+ QGraphicsWidget *e = createItem(minSize, pref, maxSize, "E");
+
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
+ l->setContentsMargins(0, 0, 0, 0);
+ l->setSpacing(0);
+
+ // vertical
+ l->addAnchor(a, Qt::AnchorTop, l, Qt::AnchorTop);
+ l->addAnchor(b, Qt::AnchorTop, l, Qt::AnchorTop);
+ l->addAnchor(c, Qt::AnchorTop, a, Qt::AnchorBottom);
+ l->addAnchor(c, Qt::AnchorTop, b, Qt::AnchorBottom);
+ l->addAnchor(c, Qt::AnchorBottom, d, Qt::AnchorTop);
+ l->addAnchor(c, Qt::AnchorBottom, e, Qt::AnchorTop);
+ l->addAnchor(d, Qt::AnchorBottom, l, Qt::AnchorBottom);
+ l->addAnchor(e, Qt::AnchorBottom, l, Qt::AnchorBottom);
+
+ // horizontal
+ l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft);
+ l->addAnchor(l, Qt::AnchorLeft, d, Qt::AnchorLeft);
+ l->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorLeft);
+
+ l->addAnchor(a, Qt::AnchorRight, c, Qt::AnchorLeft);
+ l->addAnchor(c, Qt::AnchorRight, e, Qt::AnchorLeft);
+
+ l->addAnchor(b, Qt::AnchorRight, l, Qt::AnchorRight);
+ l->addAnchor(e, Qt::AnchorRight, l, Qt::AnchorRight);
+ l->addAnchor(d, Qt::AnchorRight, e, Qt::AnchorLeft);
+
+ QCOMPARE(l->count(), 5);
+
+ QGraphicsWidget p;
+ p.setLayout(l);
+
+ QSizeF layoutMinimumSize = l->effectiveSizeHint(Qt::MinimumSize);
+ QSizeF layoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize);
+ QSizeF layoutPreferredSize = l->effectiveSizeHint(Qt::PreferredSize);
+
+ QCOMPARE(layoutMinimumSize, QSizeF(30.0, 300.0));
+ QCOMPARE(layoutPreferredSize, QSizeF(170.0, 300.0));
+ QCOMPARE(layoutMaximumSize, QSizeF(190.0, 300.0));
+
+ p.resize(layoutMinimumSize);
+ QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 10.0, 100.0));
+ QCOMPARE(b->geometry(), QRectF(10.0, 0.0, 20.0, 100.0));
+ QCOMPARE(c->geometry(), QRectF(10.0, 100.0, 10.0, 100.0));
+ QCOMPARE(d->geometry(), QRectF(0.0, 200.0, 20.0, 100.0));
+ QCOMPARE(e->geometry(), QRectF(20.0, 200.0, 10.0, 100.0));
+ QCOMPARE(p.size(), layoutMinimumSize);
+
+ p.resize(layoutPreferredSize);
+ QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 70.0, 100.0));
+ QCOMPARE(b->geometry(), QRectF(70.0, 0.0, 100.0, 100.0));
+ QCOMPARE(c->geometry(), QRectF(70.0, 100.0, 30.0, 100.0));
+ QCOMPARE(d->geometry(), QRectF(0.0, 200.0, 100.0, 100.0));
+ QCOMPARE(e->geometry(), QRectF(100.0, 200.0, 70.0, 100.0));
+ QCOMPARE(p.size(), layoutPreferredSize);
+
+ p.resize(layoutMaximumSize);
+ QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 90.0, 100.0));
+ QCOMPARE(b->geometry(), QRectF(90.0, 0.0, 100.0, 100.0));
+ QCOMPARE(c->geometry(), QRectF(90.0, 100.0, 10.0, 100.0));
+ QCOMPARE(d->geometry(), QRectF(0.0, 200.0, 100.0, 100.0));
+ QCOMPARE(e->geometry(), QRectF(100.0, 200.0, 90.0, 100.0));
+ QCOMPARE(p.size(), layoutMaximumSize);
+
+ QSizeF testA(175.0, 300.0);
+ p.resize(testA);
+ QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 75.0, 100.0));
+ QCOMPARE(b->geometry(), QRectF(75.0, 0.0, 100.0, 100.0));
+ QCOMPARE(c->geometry(), QRectF(75.0, 100.0, 25.0, 100.0));
+ QCOMPARE(d->geometry(), QRectF(0.0, 200.0, 100.0, 100.0));
+ QCOMPARE(e->geometry(), QRectF(100.0, 200.0, 75.0, 100.0));
+ QCOMPARE(p.size(), testA);
+
+ if (hasSimplification) {
+ QVERIFY(usedSimplex(l, Qt::Horizontal));
+ QVERIFY(!usedSimplex(l, Qt::Vertical));
+ }
+
+ QVERIFY(p.layout());
+ QCOMPARE(checkReverseDirection(&p), true);
+
+ c->setMinimumWidth(300);
+ QVERIFY(layoutHasConflict(l));
+}
+
+void tst_QGraphicsAnchorLayout::parallel()
+{
+ QGraphicsWidget *a = createItem(QSizeF(100, 100),
+ QSizeF(150, 100),
+ QSizeF(200, 100), "A");
+
+ QGraphicsWidget *b = createItem(QSizeF(100, 100),
+ QSizeF(150, 100),
+ QSizeF(300, 100), "B");
+
+ QGraphicsWidget *c = createItem(QSizeF(100, 100),
+ QSizeF(200, 100),
+ QSizeF(350, 100), "C");
+
+ QGraphicsWidget *d = createItem(QSizeF(100, 100),
+ QSizeF(170, 100),
+ QSizeF(200, 100), "D");
+
+ QGraphicsWidget *e = createItem(QSizeF(150, 100),
+ QSizeF(150, 100),
+ QSizeF(200, 100), "E");
+
+ QGraphicsWidget *f = createItem(QSizeF(100, 100),
+ QSizeF(150, 100),
+ QSizeF(200, 100), "F");
+
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
+ l->setContentsMargins(0, 0, 0, 0);
+ l->setSpacing(0);
+
+ l->addAnchor(l, Qt::AnchorTop, a, Qt::AnchorTop);
+ l->addAnchor(a, Qt::AnchorBottom, b, Qt::AnchorTop);
+ l->addAnchor(b, Qt::AnchorBottom, c, Qt::AnchorTop);
+ l->addAnchor(c, Qt::AnchorBottom, d, Qt::AnchorTop);
+ l->addAnchor(d, Qt::AnchorBottom, e, Qt::AnchorTop);
+ l->addAnchor(e, Qt::AnchorBottom, f, Qt::AnchorTop);
+ l->addAnchor(f, Qt::AnchorBottom, l, Qt::AnchorBottom);
+
+ l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft);
+ l->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorLeft);
+ l->addAnchor(a, Qt::AnchorRight, c, Qt::AnchorLeft);
+ l->addAnchor(b, Qt::AnchorRight, d, Qt::AnchorLeft);
+ l->addAnchor(b, Qt::AnchorRight, e, Qt::AnchorLeft);
+ l->addAnchor(c, Qt::AnchorRight, f, Qt::AnchorLeft);
+ l->addAnchor(d, Qt::AnchorRight, f, Qt::AnchorLeft);
+ l->addAnchor(e, Qt::AnchorRight, f, Qt::AnchorLeft);
+ l->addAnchor(f, Qt::AnchorRight, l, Qt::AnchorRight);
+
+ QCOMPARE(l->count(), 6);
+
+ QGraphicsWidget p;
+ p.setLayout(l);
+
+ QSizeF layoutMinimumSize = l->effectiveSizeHint(Qt::MinimumSize);
+ QSizeF layoutPreferredSize = l->effectiveSizeHint(Qt::PreferredSize);
+ QSizeF layoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize);
+
+ QCOMPARE(layoutMinimumSize, QSizeF(450, 600));
+ QCOMPARE(layoutPreferredSize, QSizeF(620, 600));
+ QCOMPARE(layoutMaximumSize, QSizeF(750, 600));
+
+ p.resize(layoutMinimumSize);
+ QCOMPARE(a->geometry(), QRectF(0, 0, 100, 100));
+ QCOMPARE(b->geometry(), QRectF(100, 100, 100, 100));
+ QCOMPARE(c->geometry(), QRectF(100, 200, 250, 100));
+ QCOMPARE(d->geometry(), QRectF(200, 300, 150, 100));
+ QCOMPARE(e->geometry(), QRectF(200, 400, 150, 100));
+ QCOMPARE(f->geometry(), QRectF(350, 500, 100, 100));
+ QCOMPARE(p.size(), layoutMinimumSize);
+
+ if (!hasSimplification)
+ return;
+
+ p.resize(layoutPreferredSize);
+ QCOMPARE(a->geometry(), QRectF(0, 0, 150, 100));
+ QCOMPARE(b->geometry(), QRectF(150, 100, 150, 100));
+ QCOMPARE(c->geometry(), QRectF(150, 200, 320, 100));
+ QCOMPARE(d->geometry(), QRectF(300, 300, 170, 100));
+ QCOMPARE(e->geometry(), QRectF(300, 400, 170, 100));
+ QCOMPARE(f->geometry(), QRectF(470, 500, 150, 100));
+ QCOMPARE(p.size(), layoutPreferredSize);
+
+ // Maximum size depends on simplification / fair distribution
+ // Without that, test may or may not pass, depending on the
+ // solution found by the solver at runtime.
+ p.resize(layoutMaximumSize);
+ QCOMPARE(a->geometry(), QRectF(0, 0, 200, 100));
+ QCOMPARE(b->geometry(), QRectF(200, 100, 175, 100));
+ QCOMPARE(c->geometry(), QRectF(200, 200, 350, 100));
+ QCOMPARE(d->geometry(), QRectF(375, 300, 175, 100));
+ QCOMPARE(e->geometry(), QRectF(375, 400, 175, 100));
+ QCOMPARE(f->geometry(), QRectF(550, 500, 200, 100));
+ QCOMPARE(p.size(), layoutMaximumSize);
+
+ QVERIFY(!usedSimplex(l, Qt::Horizontal));
+ QVERIFY(!usedSimplex(l, Qt::Vertical));
+}
+
+void tst_QGraphicsAnchorLayout::parallel2()
+{
+ QGraphicsWidget *a = createItem(QSizeF(70.0, 100.0),
+ QSizeF(100.0, 100.0),
+ QSizeF(200.0, 100.0), "A");
+
+ QGraphicsWidget *b = createItem(QSizeF(100.0, 100.0),
+ QSizeF(150.0, 100.0),
+ QSizeF(190.0, 100.0), "B");
+
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
+ l->setContentsMargins(0, 0, 0, 0);
+ l->setSpacing(0);
+
+ l->addAnchor(l, Qt::AnchorTop, a, Qt::AnchorTop);
+ l->addAnchor(a, Qt::AnchorBottom, b, Qt::AnchorTop);
+ l->addAnchor(b, Qt::AnchorBottom, l, Qt::AnchorBottom);
+
+ l->addAnchors(l, a, Qt::Horizontal);
+ l->addAnchor(l, Qt::AnchorLeft, b, Qt::AnchorLeft);
+ l->addAnchor(b, Qt::AnchorRight, a, Qt::AnchorRight);
+
+ QCOMPARE(l->count(), 2);
+
+ QGraphicsWidget p;
+ p.setLayout(l);
+
+ QSizeF layoutMinimumSize = l->effectiveSizeHint(Qt::MinimumSize);
+ QSizeF layoutPreferredSize = l->effectiveSizeHint(Qt::PreferredSize);
+ QSizeF layoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize);
+
+ QCOMPARE(layoutMinimumSize, QSizeF(100.0, 200.0));
+ QCOMPARE(layoutPreferredSize, QSizeF(150.0, 200.0));
+ QCOMPARE(layoutMaximumSize, QSizeF(190.0, 200.0));
+
+ p.resize(layoutMinimumSize);
+ QCOMPARE(p.size(), layoutMinimumSize);
+
+ p.resize(layoutPreferredSize);
+ QCOMPARE(p.size(), layoutPreferredSize);
+
+ p.resize(layoutMaximumSize);
+ QCOMPARE(p.size(), layoutMaximumSize);
+
+ if (hasSimplification) {
+ QVERIFY(!usedSimplex(l, Qt::Horizontal));
+ QVERIFY(!usedSimplex(l, Qt::Vertical));
+ }
+}
+
+void tst_QGraphicsAnchorLayout::snake()
+{
+ QGraphicsWidget *a = createItem(QSizeF(50.0, 100.0),
+ QSizeF(70.0, 100.0),
+ QSizeF(100.0, 100.0), "A");
+
+ QGraphicsWidget *b = createItem(QSizeF(10.0, 100.0),
+ QSizeF(20.0, 100.0),
+ QSizeF(40.0, 100.0), "B");
+
+ QGraphicsWidget *c = createItem(QSizeF(50.0, 100.0),
+ QSizeF(70.0, 100.0),
+ QSizeF(100.0, 100.0), "C");
+
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
+ l->setContentsMargins(0, 0, 0, 0);
+ l->setSpacing(0);
+
+ l->addAnchor(l, Qt::AnchorTop, a, Qt::AnchorTop);
+ l->addAnchor(a, Qt::AnchorBottom, b, Qt::AnchorTop);
+ l->addAnchor(b, Qt::AnchorBottom, c, Qt::AnchorTop);
+ l->addAnchor(c, Qt::AnchorBottom, l, Qt::AnchorBottom);
+
+ l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft);
+ l->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorRight);
+ l->addAnchor(b, Qt::AnchorLeft, c, Qt::AnchorLeft);
+ l->addAnchor(c, Qt::AnchorRight, l, Qt::AnchorRight);
+
+ QCOMPARE(l->count(), 3);
+
+ QGraphicsWidget p;
+ p.setLayout(l);
+
+ QSizeF layoutMinimumSize = l->effectiveSizeHint(Qt::MinimumSize);
+ QSizeF layoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize);
+ QSizeF layoutPreferredSize = l->effectiveSizeHint(Qt::PreferredSize);
+
+ QCOMPARE(layoutMinimumSize, QSizeF(60.0, 300.0));
+ QCOMPARE(layoutPreferredSize, QSizeF(120.0, 300.0));
+ QCOMPARE(layoutMaximumSize, QSizeF(190.0, 300.0));
+
+ p.resize(layoutMinimumSize);
+ QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 50.0, 100.0));
+ QCOMPARE(b->geometry(), QRectF(10.0, 100.0, 40.0, 100.0));
+ QCOMPARE(c->geometry(), QRectF(10.0, 200.0, 50.0, 100.0));
+ QCOMPARE(p.size(), layoutMinimumSize);
+
+ p.resize(layoutPreferredSize);
+ QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 70.0, 100.0));
+ QCOMPARE(b->geometry(), QRectF(50.0, 100.0, 20.0, 100.0));
+ QCOMPARE(c->geometry(), QRectF(50.0, 200.0, 70.0, 100.0));
+ QCOMPARE(p.size(), layoutPreferredSize);
+
+ p.resize(layoutMaximumSize);
+ QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 100.0, 100.0));
+ QCOMPARE(b->geometry(), QRectF(90.0, 100.0, 10.0, 100.0));
+ QCOMPARE(c->geometry(), QRectF(90.0, 200.0, 100.0, 100.0));
+ QCOMPARE(p.size(), layoutMaximumSize);
+
+ QVERIFY(layoutHasConflict(l) == false);
+
+ // Test QSizePolicy::ExpandFlag, it shouldn't change the extreme
+ // points of the layout...
+ b->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+
+ QSizeF newLayoutMinimumSize = l->effectiveSizeHint(Qt::MinimumSize);
+ QSizeF newLayoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize);
+ QSizeF newLayoutPreferredSize = l->effectiveSizeHint(Qt::PreferredSize);
+
+ QCOMPARE(layoutMinimumSize, newLayoutMinimumSize);
+ QCOMPARE(layoutMaximumSize, newLayoutMaximumSize);
+ QCOMPARE(layoutPreferredSize, newLayoutPreferredSize);
+}
+
+void tst_QGraphicsAnchorLayout::snakeOppositeDirections()
+{
+ QGraphicsWidget *a = createItem(QSizeF(50.0, 100.0),
+ QSizeF(70.0, 100.0),
+ QSizeF(100.0, 100.0), "A");
+
+ QGraphicsWidget *b = createItem(QSizeF(10.0, 100.0),
+ QSizeF(20.0, 100.0),
+ QSizeF(40.0, 100.0), "B");
+
+ QGraphicsWidget *c = createItem(QSizeF(50.0, 100.0),
+ QSizeF(70.0, 100.0),
+ QSizeF(100.0, 100.0), "C");
+
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
+ l->setContentsMargins(0, 0, 0, 0);
+ l->setSpacing(0);
+
+ l->addAnchor(l, Qt::AnchorTop, a, Qt::AnchorTop);
+ l->addAnchor(a, Qt::AnchorBottom, b, Qt::AnchorTop);
+ l->addAnchor(b, Qt::AnchorBottom, c, Qt::AnchorTop);
+ l->addAnchor(c, Qt::AnchorBottom, l, Qt::AnchorBottom);
+
+ l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft);
+
+ // Both a and c are 'pointing' to b
+ l->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorRight);
+ l->addAnchor(c, Qt::AnchorLeft, b, Qt::AnchorLeft);
+
+ l->addAnchor(c, Qt::AnchorRight, l, Qt::AnchorRight);
+
+ QCOMPARE(l->count(), 3);
+
+ QGraphicsWidget p;
+ p.setLayout(l);
+
+ QSizeF layoutMinimumSize = l->effectiveSizeHint(Qt::MinimumSize);
+ QSizeF layoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize);
+ QSizeF layoutPreferredSize = l->effectiveSizeHint(Qt::PreferredSize);
+
+ QCOMPARE(layoutMinimumSize, QSizeF(60.0, 300.0));
+ QCOMPARE(layoutPreferredSize, QSizeF(120.0, 300.0));
+ QCOMPARE(layoutMaximumSize, QSizeF(190.0, 300.0));
+
+ p.resize(layoutMinimumSize);
+ QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 50.0, 100.0));
+ QCOMPARE(b->geometry(), QRectF(10.0, 100.0, 40.0, 100.0));
+ QCOMPARE(c->geometry(), QRectF(10.0, 200.0, 50.0, 100.0));
+ QCOMPARE(p.size(), layoutMinimumSize);
+
+ p.resize(layoutPreferredSize);
+ QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 70.0, 100.0));
+ QCOMPARE(b->geometry(), QRectF(50.0, 100.0, 20.0, 100.0));
+ QCOMPARE(c->geometry(), QRectF(50.0, 200.0, 70.0, 100.0));
+ QCOMPARE(p.size(), layoutPreferredSize);
+
+ p.resize(layoutMaximumSize);
+ QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 100.0, 100.0));
+ QCOMPARE(b->geometry(), QRectF(90.0, 100.0, 10.0, 100.0));
+ QCOMPARE(c->geometry(), QRectF(90.0, 200.0, 100.0, 100.0));
+ QCOMPARE(p.size(), layoutMaximumSize);
+
+ QVERIFY(p.layout());
+ QCOMPARE(checkReverseDirection(&p), true);
+}
+
+void tst_QGraphicsAnchorLayout::fairDistribution()
+{
+ QGraphicsWidget *a = createItem(QSizeF(10.0, 100.0),
+ QSizeF(50.0, 100.0),
+ QSizeF(100.0, 100.0), "A");
+
+ QGraphicsWidget *b = createItem(QSizeF(10.0, 100.0),
+ QSizeF(50.0, 100.0),
+ QSizeF(100.0, 100.0), "B");
+
+ QGraphicsWidget *c = createItem(QSizeF(10.0, 100.0),
+ QSizeF(50.0, 100.0),
+ QSizeF(100.0, 100.0), "C");
+
+ QGraphicsWidget *d = createItem(QSizeF(60.0, 100.0),
+ QSizeF(165.0, 100.0),
+ QSizeF(600.0, 100.0), "D");
+
+
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
+ l->setContentsMargins(0, 0, 0, 0);
+ l->setSpacing(0);
+
+ l->addAnchor(l, Qt::AnchorTop, a, Qt::AnchorTop);
+ l->addAnchor(a, Qt::AnchorBottom, b, Qt::AnchorTop);
+ l->addAnchor(b, Qt::AnchorBottom, c, Qt::AnchorTop);
+ l->addAnchor(c, Qt::AnchorBottom, d, Qt::AnchorTop);
+ l->addAnchor(d, Qt::AnchorBottom, l, Qt::AnchorBottom);
+
+ l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft);
+ l->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorLeft);
+ l->addAnchor(b, Qt::AnchorRight, c, Qt::AnchorLeft);
+ l->addAnchor(c, Qt::AnchorRight, l, Qt::AnchorRight);
+ l->addAnchor(l, Qt::AnchorLeft, d, Qt::AnchorLeft);
+ l->addAnchor(d, Qt::AnchorRight, l, Qt::AnchorRight);
+
+ QCOMPARE(l->count(), 4);
+
+ QGraphicsWidget p;
+ p.setLayout(l);
+
+ QSizeF layoutMinimumSize = l->effectiveSizeHint(Qt::MinimumSize);
+ QSizeF layoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize);
+ QSizeF layoutPreferredSize = l->effectiveSizeHint(Qt::PreferredSize);
+
+ QCOMPARE(layoutMinimumSize, QSizeF(60.0, 400.0));
+ QCOMPARE(layoutPreferredSize, QSizeF(165.0, 400.0));
+ QCOMPARE(layoutMaximumSize, QSizeF(300.0, 400.0));
+
+ p.resize(layoutMinimumSize);
+ if (!hasSimplification)
+ QEXPECT_FAIL("", "Without simplification there is no fair distribution.", Abort);
+ QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 20.0, 100.0));
+ QCOMPARE(b->geometry(), QRectF(20.0, 100.0, 20.0, 100.0));
+ QCOMPARE(c->geometry(), QRectF(40.0, 200.0, 20.0, 100.0));
+ QCOMPARE(d->geometry(), QRectF(0.0, 300.0, 60.0, 100.0));
+ QCOMPARE(p.size(), layoutMinimumSize);
+
+ p.resize(layoutPreferredSize);
+ QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 55.0, 100.0));
+ QCOMPARE(b->geometry(), QRectF(55.0, 100.0, 55.0, 100.0));
+ QCOMPARE(c->geometry(), QRectF(110.0, 200.0, 55.0, 100.0));
+ QCOMPARE(d->geometry(), QRectF(0.0, 300.0, 165.0, 100.0));
+ QCOMPARE(p.size(), layoutPreferredSize);
+
+ p.resize(layoutMaximumSize);
+ QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 100.0, 100.0));
+ QCOMPARE(b->geometry(), QRectF(100.0, 100.0, 100.0, 100.0));
+ QCOMPARE(c->geometry(), QRectF(200.0, 200.0, 100.0, 100.0));
+ QCOMPARE(d->geometry(), QRectF(0.0, 300.0, 300.0, 100.0));
+ QCOMPARE(p.size(), layoutMaximumSize);
+
+ if (hasSimplification) {
+ QVERIFY(!usedSimplex(l, Qt::Horizontal));
+ QVERIFY(!usedSimplex(l, Qt::Vertical));
+ }
+}
+
+void tst_QGraphicsAnchorLayout::fairDistributionOppositeDirections()
+{
+ QGraphicsWidget *a = createItem(QSizeF(10.0, 100.0),
+ QSizeF(50.0, 100.0),
+ QSizeF(100.0, 100.0), "A");
+
+ QGraphicsWidget *b = createItem(QSizeF(10.0, 100.0),
+ QSizeF(50.0, 100.0),
+ QSizeF(100.0, 100.0), "B");
+
+ QGraphicsWidget *c = createItem(QSizeF(10.0, 100.0),
+ QSizeF(50.0, 100.0),
+ QSizeF(100.0, 100.0), "C");
+
+ QGraphicsWidget *d = createItem(QSizeF(10.0, 100.0),
+ QSizeF(50.0, 100.0),
+ QSizeF(100.0, 100.0), "D");
+
+ QGraphicsWidget *e = createItem(QSizeF(60.0, 100.0),
+ QSizeF(220.0, 100.0),
+ QSizeF(600.0, 100.0), "E");
+
+
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
+ l->setContentsMargins(0, 0, 0, 0);
+ l->setSpacing(0);
+
+ l->addAnchor(l, Qt::AnchorTop, a, Qt::AnchorTop);
+ l->addAnchor(a, Qt::AnchorBottom, b, Qt::AnchorTop);
+ l->addAnchor(b, Qt::AnchorBottom, c, Qt::AnchorTop);
+ l->addAnchor(c, Qt::AnchorBottom, d, Qt::AnchorTop);
+ l->addAnchor(d, Qt::AnchorBottom, e, Qt::AnchorTop);
+ l->addAnchor(e, Qt::AnchorBottom, l, Qt::AnchorBottom);
+
+ l->addAnchor(a, Qt::AnchorLeft, l, Qt::AnchorLeft);
+ l->addAnchor(b, Qt::AnchorLeft, a, Qt::AnchorRight);
+ l->addAnchor(c, Qt::AnchorLeft, b, Qt::AnchorRight);
+ l->addAnchor(d, Qt::AnchorLeft, c, Qt::AnchorRight);
+ l->addAnchor(d, Qt::AnchorRight, l, Qt::AnchorRight);
+ l->addAnchors(l, e, Qt::Horizontal);
+
+ QCOMPARE(l->count(), 5);
+
+ QGraphicsWidget p;
+ p.setLayout(l);
+
+ QSizeF layoutMinimumSize = l->effectiveSizeHint(Qt::MinimumSize);
+ QSizeF layoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize);
+ QSizeF layoutPreferredSize = l->effectiveSizeHint(Qt::PreferredSize);
+
+ QCOMPARE(layoutMinimumSize, QSizeF(60.0, 500.0));
+ QCOMPARE(layoutPreferredSize, QSizeF(220.0, 500.0));
+ QCOMPARE(layoutMaximumSize, QSizeF(400.0, 500.0));
+
+ if (!hasSimplification)
+ return;
+
+ p.resize(layoutMinimumSize);
+ QCOMPARE(a->size(), b->size());
+ QCOMPARE(a->size(), c->size());
+ QCOMPARE(a->size(), d->size());
+ QCOMPARE(e->size().width(), 4 * a->size().width());
+ QCOMPARE(p.size(), layoutMinimumSize);
+
+ p.resize(layoutPreferredSize);
+ QCOMPARE(a->size(), b->size());
+ QCOMPARE(a->size(), c->size());
+ QCOMPARE(a->size(), d->size());
+ QCOMPARE(e->size().width(), 4 * a->size().width());
+ QCOMPARE(p.size(), layoutPreferredSize);
+
+ p.resize(layoutMaximumSize);
+ QCOMPARE(a->size(), b->size());
+ QCOMPARE(a->size(), c->size());
+ QCOMPARE(a->size(), d->size());
+ QCOMPARE(e->size().width(), 4 * a->size().width());
+ QCOMPARE(p.size(), layoutMaximumSize);
+
+ QVERIFY(!usedSimplex(l, Qt::Horizontal));
+ QVERIFY(!usedSimplex(l, Qt::Vertical));
+}
+
+void tst_QGraphicsAnchorLayout::proportionalPreferred()
+{
+ QSizeF minSize(0, 100);
+
+ QGraphicsWidget *a = createItem(minSize, QSizeF(10, 100), QSizeF(20, 100), "A");
+ QGraphicsWidget *b = createItem(minSize, QSizeF(20, 100), QSizeF(30, 100), "B");
+ QGraphicsWidget *c = createItem(minSize, QSizeF(14, 100), QSizeF(20, 100), "C");
+ QGraphicsWidget *d = createItem(minSize, QSizeF(10, 100), QSizeF(20, 100), "D");
+
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
+ l->setContentsMargins(0, 0, 0, 0);
+ l->setSpacing(0);
+
+ l->addAnchor(l, Qt::AnchorTop, a, Qt::AnchorTop);
+ l->addAnchor(a, Qt::AnchorBottom, b, Qt::AnchorTop);
+ l->addAnchor(b, Qt::AnchorBottom, c, Qt::AnchorTop);
+ l->addAnchor(c, Qt::AnchorBottom, d, Qt::AnchorTop);
+ l->addAnchor(d, Qt::AnchorBottom, l, Qt::AnchorBottom);
+
+ l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft);
+ l->addAnchor(l, Qt::AnchorLeft, b, Qt::AnchorLeft);
+ l->addAnchor(a, Qt::AnchorRight, c, Qt::AnchorLeft);
+ l->addAnchor(a, Qt::AnchorRight, d, Qt::AnchorLeft);
+ l->addAnchor(b, Qt::AnchorRight, l, Qt::AnchorRight);
+ l->addAnchor(c, Qt::AnchorRight, l, Qt::AnchorRight);
+ l->addAnchor(d, Qt::AnchorRight, l, Qt::AnchorRight);
+
+ QCOMPARE(l->count(), 4);
+
+ QGraphicsWidget p;
+ p.setLayout(l);
+
+ QSizeF layoutMinimumSize = l->effectiveSizeHint(Qt::MinimumSize);
+ QSizeF layoutPreferredSize = l->effectiveSizeHint(Qt::PreferredSize);
+ QSizeF layoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize);
+
+ QCOMPARE(layoutMinimumSize, QSizeF(0, 400));
+ QCOMPARE(layoutPreferredSize, QSizeF(24, 400));
+ QCOMPARE(layoutMaximumSize, QSizeF(30, 400));
+
+ p.resize(layoutMinimumSize);
+ QCOMPARE(p.size(), layoutMinimumSize);
+
+ p.resize(layoutPreferredSize);
+ QCOMPARE(c->size().width(), d->size().width());
+ QCOMPARE(p.size(), layoutPreferredSize);
+
+ p.resize(layoutMaximumSize);
+ QCOMPARE(p.size(), layoutMaximumSize);
+
+ p.resize(QSizeF(12, 400));
+
+ // Proportionality between size given and preferred size, this
+ // should be respected in this graph for (a) and (b)|(c).
+ qreal factor = 12.0 / 24.0;
+
+ QCOMPARE(c->size().width(), d->size().width());
+ QCOMPARE(a->size().width(), 10 * factor);
+ QCOMPARE(c->size().width(), 14 * factor);
+ QCOMPARE(p.size(), QSizeF(12, 400));
+
+ if (hasSimplification) {
+ QVERIFY(!usedSimplex(l, Qt::Horizontal));
+ QVERIFY(!usedSimplex(l, Qt::Vertical));
+ }
+}
+
+void tst_QGraphicsAnchorLayout::example()
+{
+ QSizeF minSize(30, 100);
+ QSizeF pref(210, 100);
+ QSizeF maxSize(300, 100);
+
+ QGraphicsWidget *a = createItem(minSize, pref, maxSize, "A");
+ QGraphicsWidget *b = createItem(minSize, pref, maxSize, "B");
+ QGraphicsWidget *c = createItem(minSize, pref, maxSize, "C");
+ QGraphicsWidget *d = createItem(minSize, pref, maxSize, "D");
+ QGraphicsWidget *e = createItem(minSize, pref, maxSize, "E");
+ QGraphicsWidget *f = createItem(QSizeF(30, 50), QSizeF(150, 50), maxSize, "F");
+ QGraphicsWidget *g = createItem(QSizeF(30, 50), QSizeF(30, 100), maxSize, "G");
+
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
+ l->setContentsMargins(0, 0, 0, 0);
+ l->setSpacing(0);
+
+ // vertical
+ l->addAnchor(a, Qt::AnchorTop, l, Qt::AnchorTop);
+ l->addAnchor(b, Qt::AnchorTop, l, Qt::AnchorTop);
+
+ l->addAnchor(c, Qt::AnchorTop, a, Qt::AnchorBottom);
+ l->addAnchor(c, Qt::AnchorTop, b, Qt::AnchorBottom);
+ l->addAnchor(c, Qt::AnchorBottom, d, Qt::AnchorTop);
+ l->addAnchor(c, Qt::AnchorBottom, e, Qt::AnchorTop);
+
+ l->addAnchor(d, Qt::AnchorBottom, l, Qt::AnchorBottom);
+ l->addAnchor(e, Qt::AnchorBottom, l, Qt::AnchorBottom);
+
+ l->addAnchor(c, Qt::AnchorTop, f, Qt::AnchorTop);
+ l->addAnchor(c, Qt::AnchorVerticalCenter, f, Qt::AnchorBottom);
+ l->addAnchor(f, Qt::AnchorBottom, g, Qt::AnchorTop);
+ l->addAnchor(c, Qt::AnchorBottom, g, Qt::AnchorBottom);
+
+ // horizontal
+ l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft);
+ l->addAnchor(l, Qt::AnchorLeft, d, Qt::AnchorLeft);
+ l->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorLeft);
+
+ l->addAnchor(a, Qt::AnchorRight, c, Qt::AnchorLeft);
+ l->addAnchor(c, Qt::AnchorRight, e, Qt::AnchorLeft);
+
+ l->addAnchor(b, Qt::AnchorRight, l, Qt::AnchorRight);
+ l->addAnchor(e, Qt::AnchorRight, l, Qt::AnchorRight);
+ l->addAnchor(d, Qt::AnchorRight, e, Qt::AnchorLeft);
+
+ l->addAnchor(l, Qt::AnchorLeft, f, Qt::AnchorLeft);
+ l->addAnchor(l, Qt::AnchorLeft, g, Qt::AnchorLeft);
+ l->addAnchor(f, Qt::AnchorRight, g, Qt::AnchorRight);
+
+ QCOMPARE(l->count(), 7);
+
+ QGraphicsWidget p;
+ p.setLayout(l);
+
+ QSizeF layoutMinimumSize = l->effectiveSizeHint(Qt::MinimumSize);
+ QSizeF layoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize);
+ QSizeF layoutPreferredSize = l->effectiveSizeHint(Qt::PreferredSize);
+
+ QCOMPARE(layoutMinimumSize, QSizeF(90.0, 300.0));
+ QCOMPARE(layoutPreferredSize, QSizeF(510.0, 300.0));
+ QCOMPARE(layoutMaximumSize, QSizeF(570.0, 300.0));
+
+ p.resize(layoutMinimumSize);
+ QCOMPARE(p.size(), layoutMinimumSize);
+ QCOMPARE(a->size(), e->size());
+ QCOMPARE(b->size(), d->size());
+ QCOMPARE(f->size(), g->size());
+
+ p.resize(layoutPreferredSize);
+ QCOMPARE(p.size(), layoutPreferredSize);
+ QCOMPARE(a->size(), e->size());
+ QCOMPARE(b->size(), d->size());
+ QCOMPARE(f->size(), g->size());
+
+ p.resize(layoutMaximumSize);
+ QCOMPARE(p.size(), layoutMaximumSize);
+ QCOMPARE(a->size(), e->size());
+ QCOMPARE(b->size(), d->size());
+ QCOMPARE(f->size(), g->size());
+
+ if (hasSimplification) {
+ QVERIFY(usedSimplex(l, Qt::Horizontal));
+ QVERIFY(usedSimplex(l, Qt::Vertical));
+ }
+}
+
+void tst_QGraphicsAnchorLayout::setSpacing()
+{
+ QSizeF minSize(10, 10);
+ QSizeF pref(20, 20);
+ QSizeF maxSize(50, 50);
+
+ QGraphicsWidget *a = createItem(minSize, pref, maxSize);
+ QGraphicsWidget *b = createItem(minSize, pref, maxSize);
+ QGraphicsWidget *c = createItem(minSize, pref, maxSize);
+
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
+ l->addCornerAnchors(l, Qt::TopLeftCorner, a, Qt::TopLeftCorner);
+ l->addCornerAnchors(b, Qt::TopRightCorner, l, Qt::TopRightCorner);
+ l->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorLeft);
+
+ l->addAnchors(l, c, Qt::Horizontal);
+
+ l->addAnchor(a, Qt::AnchorBottom, c, Qt::AnchorTop);
+ l->addAnchor(c, Qt::AnchorBottom, l, Qt::AnchorBottom);
+
+ QGraphicsWidget *p = new QGraphicsWidget(0, Qt::Window);
+
+ p->setLayout(l);
+ l->setSpacing(1);
+
+ // don't let the style influence the test.
+ l->setContentsMargins(0, 0, 0, 0);
+
+ QGraphicsScene scene;
+ scene.addItem(p);
+ QGraphicsView *view = new QGraphicsView(&scene);
+ view->show();
+ p->show();
+
+ QApplication::processEvents();
+#ifdef Q_WS_MAC
+ QTest::qWait(200);
+#endif
+
+ // 21x21
+ QCOMPARE(p->size(), QSizeF(41, 41));
+ QCOMPARE(a->geometry(), QRectF(0, 0, 20, 20));
+ QCOMPARE(b->geometry(), QRectF(21, 0, 20, 20));
+ QCOMPARE(c->geometry(), QRectF(0, 21, 41, 20));
+
+ l->setHorizontalSpacing(4);
+ QApplication::processEvents();
+ p->adjustSize();
+ QCOMPARE(a->geometry(), QRectF(0, 0, 20, 20));
+ QCOMPARE(b->geometry(), QRectF(24, 0, 20, 20));
+ QCOMPARE(c->geometry(), QRectF(0, 21, 44, 20));
+
+ l->setVerticalSpacing(0);
+ QApplication::processEvents();
+ p->adjustSize();
+ QCOMPARE(a->geometry(), QRectF(0, 0, 20, 20));
+ QCOMPARE(b->geometry(), QRectF(24, 0, 20, 20));
+ QCOMPARE(c->geometry(), QRectF(0, 20, 44, 20));
+
+ delete p;
+ delete view;
+}
+
+class CustomLayoutStyle : public QWindowsStyle
+{
+ Q_OBJECT
+public:
+ CustomLayoutStyle() : QWindowsStyle()
+ {
+ hspacing = 5;
+ vspacing = 10;
+ }
+
+ virtual int pixelMetric(PixelMetric metric, const QStyleOption * option = 0,
+ const QWidget * widget = 0 ) const;
+
+ int hspacing;
+ int vspacing;
+
+protected slots:
+ int layoutSpacingImplementation(QSizePolicy::ControlType control1,
+ QSizePolicy::ControlType control2,
+ Qt::Orientation orientation,
+ const QStyleOption *option = 0,
+ const QWidget *widget = 0) const;
+
+};
+
+#define CT1(c) CT2(c, c)
+#define CT2(c1, c2) ((uint)c1 << 16) | (uint)c2
+
+int CustomLayoutStyle::layoutSpacingImplementation(QSizePolicy::ControlType control1,
+ QSizePolicy::ControlType control2,
+ Qt::Orientation orientation,
+ const QStyleOption * /*option = 0*/,
+ const QWidget * /*widget = 0*/) const
+{
+ if (orientation == Qt::Horizontal) {
+ switch (CT2(control1, control2)) {
+ case CT1(QSizePolicy::PushButton):
+ return 2;
+ break;
+ }
+ return 5;
+ } else {
+ switch (CT2(control1, control2)) {
+ case CT1(QSizePolicy::RadioButton):
+ return 2;
+ break;
+
+ }
+ return 10;
+ }
+}
+
+int CustomLayoutStyle::pixelMetric(PixelMetric metric, const QStyleOption * option /*= 0*/,
+ const QWidget * widget /*= 0*/ ) const
+{
+ switch (metric) {
+ case PM_LayoutLeftMargin:
+ return 0;
+ break;
+ case PM_LayoutTopMargin:
+ return 3;
+ break;
+ case PM_LayoutRightMargin:
+ return 6;
+ break;
+ case PM_LayoutBottomMargin:
+ return 9;
+ break;
+ case PM_LayoutHorizontalSpacing:
+ return hspacing;
+ case PM_LayoutVerticalSpacing:
+ return vspacing;
+ break;
+ default:
+ break;
+ }
+ return QWindowsStyle::pixelMetric(metric, option, widget);
+}
+
+void tst_QGraphicsAnchorLayout::styleDefaults()
+{
+ QSizeF minSize (10, 10);
+ QSizeF pref(20, 20);
+ QSizeF maxSize (50, 50);
+
+ /*
+ create this layout, where a,b have controlType QSizePolicy::RadioButton
+ c,d have controlType QSizePolicy::PushButton:
+ +-------+
+ |a |
+ | b |
+ | c |
+ | d|
+ +-------+
+ */
+ QGraphicsScene scene;
+ QGraphicsWidget *a = createItem(minSize, pref, maxSize);
+ QSizePolicy spRadioButton = a->sizePolicy();
+ spRadioButton.setControlType(QSizePolicy::RadioButton);
+ a->setSizePolicy(spRadioButton);
+
+ QGraphicsWidget *b = createItem(minSize, pref, maxSize);
+ b->setSizePolicy(spRadioButton);
+
+ QGraphicsWidget *c = createItem(minSize, pref, maxSize);
+ QSizePolicy spPushButton = c->sizePolicy();
+ spPushButton.setControlType(QSizePolicy::PushButton);
+ c->setSizePolicy(spPushButton);
+
+ QGraphicsWidget *d = createItem(minSize, pref, maxSize);
+ d->setSizePolicy(spPushButton);
+
+ QGraphicsWidget *window = new QGraphicsWidget(0, Qt::Window);
+
+ // Test layoutSpacingImplementation
+ CustomLayoutStyle *style = new CustomLayoutStyle;
+ style->hspacing = -1;
+ style->vspacing = -1;
+ window->setStyle(style);
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
+
+ l->addCornerAnchors(l, Qt::TopLeftCorner, a, Qt::TopLeftCorner);
+ l->addCornerAnchors(a, Qt::BottomRightCorner, b, Qt::TopLeftCorner);
+ l->addCornerAnchors(b, Qt::BottomRightCorner, c, Qt::TopLeftCorner);
+ l->addCornerAnchors(c, Qt::BottomRightCorner, d, Qt::TopLeftCorner);
+ l->addCornerAnchors(d, Qt::BottomRightCorner, l, Qt::BottomRightCorner);
+
+ window->setLayout(l);
+
+ scene.addItem(window);
+
+ window->show();
+ QGraphicsView view(&scene);
+ view.resize(200, 200);
+ view.show();
+
+ window->adjustSize();
+ QCOMPARE(a->geometry(), QRectF(0, 3, 20, 20)); //radio
+ QCOMPARE(b->geometry(), QRectF(25, 25, 20, 20)); //radio
+ QCOMPARE(c->geometry(), QRectF(50, 55, 20, 20)); //push
+ QCOMPARE(d->geometry(), QRectF(72, 85, 20, 20)); //push
+ QCOMPARE(l->geometry(), QRectF(0, 0, 98, 114));
+
+
+ // Test pixelMetric(PM_Layout{Horizontal|Vertical}Spacing
+ window->setStyle(0);
+
+ style->hspacing = 1;
+ style->vspacing = 2;
+
+ window->setStyle(style);
+ window->adjustSize();
+ QCOMPARE(a->geometry(), QRectF(0, 3, 20, 20));
+ QCOMPARE(b->geometry(), QRectF(21, 25, 20, 20));
+ QCOMPARE(c->geometry(), QRectF(42, 47, 20, 20));
+ QCOMPARE(d->geometry(), QRectF(63, 69, 20, 20));
+ QCOMPARE(l->geometry(), QRectF(0, 0, 89, 98));
+
+ window->setStyle(0);
+ delete style;
+}
+
+
+/*!
+ Taken from "hard" complex case, found at
+ https://cwiki.nokia.com/S60QTUI/AnchorLayoutComplexCases
+
+ This layout has a special property, since it has two possible solutions for its minimum size.
+
+ For instance, when it is in its minimum size - the layout have two possible solutions:
+ 1. c.width == 10, e.width == 10 and g.width == 10
+ (all others have width 0)
+ 2. d.width == 10 and g.width == 10
+ (all others have width 0)
+
+ It also has several solutions for preferred size.
+*/
+static QGraphicsAnchorLayout *createAmbiguousS60Layout()
+{
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
+ l->setContentsMargins(0, 0, 0, 0);
+ l->setSpacing(0);
+
+ QSizeF minSize(0, 10);
+ QSizeF pref(50, 10);
+ QSizeF maxSize(100, 10);
+
+ QGraphicsWidget *a = createItem(minSize, pref, maxSize, "a");
+ QGraphicsWidget *b = createItem(minSize, pref, maxSize, "b");
+ QGraphicsWidget *c = createItem(minSize, pref, maxSize, "c");
+ QGraphicsWidget *d = createItem(minSize, pref, maxSize, "d");
+ QGraphicsWidget *e = createItem(minSize, pref, maxSize, "e");
+ QGraphicsWidget *f = createItem(minSize, pref, maxSize, "f");
+ QGraphicsWidget *g = createItem(minSize, pref, maxSize, "g");
+
+ //<!-- Trunk -->
+ setAnchor(l, l, Qt::AnchorLeft, a, Qt::AnchorLeft, 10);
+ setAnchor(l, a, Qt::AnchorRight, b, Qt::AnchorLeft, 10);
+ setAnchor(l, b, Qt::AnchorRight, c, Qt::AnchorLeft, 10);
+ setAnchor(l, c, Qt::AnchorRight, d, Qt::AnchorLeft, 10);
+ setAnchor(l, d, Qt::AnchorRight, l, Qt::AnchorRight, 10);
+
+ //<!-- Above trunk -->
+ setAnchor(l, b, Qt::AnchorLeft, e, Qt::AnchorLeft, 10);
+ setAnchor(l, e, Qt::AnchorRight, d, Qt::AnchorLeft, 10);
+
+ //<!-- Below trunk -->
+ setAnchor(l, a, Qt::AnchorHorizontalCenter, g, Qt::AnchorLeft, 10);
+ setAnchor(l, g, Qt::AnchorRight, f, Qt::AnchorHorizontalCenter, 10);
+ setAnchor(l, c, Qt::AnchorLeft, f, Qt::AnchorLeft, 10);
+ setAnchor(l, f, Qt::AnchorRight, d, Qt::AnchorRight, 10);
+
+ //<!-- vertical is simpler -->
+ setAnchor(l, l, Qt::AnchorTop, e, Qt::AnchorTop, 0);
+ setAnchor(l, e, Qt::AnchorBottom, a, Qt::AnchorTop, 0);
+ setAnchor(l, e, Qt::AnchorBottom, b, Qt::AnchorTop, 0);
+ setAnchor(l, e, Qt::AnchorBottom, c, Qt::AnchorTop, 0);
+ setAnchor(l, e, Qt::AnchorBottom, d, Qt::AnchorTop, 0);
+ setAnchor(l, a, Qt::AnchorBottom, f, Qt::AnchorTop, 0);
+ setAnchor(l, a, Qt::AnchorBottom, b, Qt::AnchorBottom, 0);
+ setAnchor(l, a, Qt::AnchorBottom, c, Qt::AnchorBottom, 0);
+ setAnchor(l, a, Qt::AnchorBottom, d, Qt::AnchorBottom, 0);
+ setAnchor(l, f, Qt::AnchorBottom, g, Qt::AnchorTop, 0);
+ setAnchor(l, g, Qt::AnchorBottom, l, Qt::AnchorBottom, 0);
+ return l;
+}
+
+void tst_QGraphicsAnchorLayout::hardComplexS60()
+{
+ QGraphicsAnchorLayout *l = createAmbiguousS60Layout();
+ QCOMPARE(l->count(), 7);
+
+ QGraphicsWidget *p = new QGraphicsWidget(0, Qt::Window);
+ p->setLayout(l);
+
+ QSizeF layoutMinimumSize = l->effectiveSizeHint(Qt::MinimumSize);
+ QCOMPARE(layoutMinimumSize, QSizeF(60, 40));
+ // expected preferred might be wrong, (haven't manually verified it)
+ QSizeF layoutPreferredSize = l->effectiveSizeHint(Qt::PreferredSize);
+ QCOMPARE(layoutPreferredSize, QSizeF(220, 40));
+ QSizeF layoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize);
+ QCOMPARE(layoutMaximumSize, QSizeF(240, 40));
+
+ delete p;
+}
+
+void tst_QGraphicsAnchorLayout::stability()
+{
+ QVector<QRectF> geometries;
+ geometries.resize(7);
+ QGraphicsWidget *p = new QGraphicsWidget(0, Qt::Window);
+ bool sameAsPreviousArrangement = true;
+ // it usually fails after 3-4 iterations
+ for (int pass = 0; pass < 20 && sameAsPreviousArrangement; ++pass) {
+ // In case we need to "scramble" the heap allocator to provoke this bug.
+ //static const int primes[] = {2, 3, 5, 13, 89, 233, 1597, 28657, 514229}; // fibo primes
+ //const int primeCount = sizeof(primes)/sizeof(int);
+ //int alloc = primes[pass % primeCount] + pass;
+ //void *mem = qMalloc(alloc);
+ //qFree(mem);
+ QGraphicsAnchorLayout *l = createAmbiguousS60Layout();
+ p->setLayout(l);
+ QSizeF layoutMinimumSize = l->effectiveSizeHint(Qt::MinimumSize);
+ l->setGeometry(QRectF(QPointF(0,0), layoutMinimumSize));
+ QApplication::processEvents();
+ for (int i = l->count() - 1; i >=0 && sameAsPreviousArrangement; --i) {
+ QRectF geom = l->itemAt(i)->geometry();
+ if (pass != 0) {
+ sameAsPreviousArrangement = (geometries[i] == geom);
+ }
+ geometries[i] = geom;
+ }
+ p->setLayout(0); // uninstalls and deletes the layout
+ QApplication::processEvents();
+ }
+ delete p;
+ QEXPECT_FAIL("", "The layout have several solutions, but which solution it picks is not stable", Continue);
+ QCOMPARE(sameAsPreviousArrangement, true);
+}
+
+void tst_QGraphicsAnchorLayout::delete_anchor()
+{
+ QGraphicsScene scene;
+ QSizeF minSize(0, 0);
+ QSizeF prefSize(50, 50);
+ QSizeF maxSize(100, 100);
+ QGraphicsWidget *w1 = createItem(minSize, prefSize, maxSize, "w1");
+ QGraphicsWidget *w2 = createItem(minSize, prefSize, maxSize, "w2");
+ QGraphicsWidget *w3 = createItem(minSize, prefSize, maxSize, "w3");
+
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
+ l->setSpacing(0);
+ l->setContentsMargins(0, 0, 0, 0);
+
+ // Horizontal
+ l->addAnchor(l, Qt::AnchorLeft, w1, Qt::AnchorLeft);
+ l->addAnchor(w1, Qt::AnchorRight, w2, Qt::AnchorLeft);
+ l->addAnchor(w2, Qt::AnchorRight, l, Qt::AnchorRight);
+ l->addAnchor(w1, Qt::AnchorRight, w3, Qt::AnchorLeft);
+ l->addAnchor(w3, Qt::AnchorRight, l, Qt::AnchorRight);
+
+ // Vertical
+ l->addAnchors(l, w1, Qt::Vertical);
+ l->addAnchors(l, w2, Qt::Vertical);
+ l->addAnchors(l, w3, Qt::Vertical);
+
+ QGraphicsAnchor *anchor = l->anchor(w3, Qt::AnchorRight, l, Qt::AnchorRight);
+ anchor->setSpacing(10);
+
+ QGraphicsWidget *p = new QGraphicsWidget;
+ p->setLayout(l);
+
+ QCOMPARE(l->count(), 3);
+
+ scene.addItem(p);
+ QGraphicsView *view = new QGraphicsView(&scene);
+ QApplication::processEvents();
+ // Should now be simplified
+ QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize).width(), qreal(110));
+ QGraphicsAnchor *anchor1 = l->anchor(w3, Qt::AnchorRight, l, Qt::AnchorRight);
+ QVERIFY(anchor1);
+ QGraphicsAnchor *anchor2 = l->anchor(w3, Qt::AnchorRight, l, Qt::AnchorRight);
+ QVERIFY(anchor2);
+ QGraphicsAnchor *anchor3 = l->anchor(l, Qt::AnchorRight, w3, Qt::AnchorRight);
+ QVERIFY(anchor3);
+ QGraphicsAnchor *anchor4 = l->anchor(l, Qt::AnchorRight, w3, Qt::AnchorRight);
+ QVERIFY(anchor4);
+
+ // should all be the same object
+ QCOMPARE(anchor1, anchor2);
+ QCOMPARE(anchor2, anchor3);
+ QCOMPARE(anchor3, anchor4);
+
+ // check if removal works
+ delete anchor1;
+
+ QApplication::processEvents();
+
+ // it should also change the preferred size of the layout
+ QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize).width(), qreal(100));
+
+ delete p;
+ delete view;
+}
+
+void tst_QGraphicsAnchorLayout::sizePolicy()
+{
+ QGraphicsScene scene;
+ QSizeF minSize(0, 0);
+ QSizeF prefSize(50, 50);
+ QSizeF maxSize(100, 100);
+ QGraphicsWidget *w1 = createItem(minSize, prefSize, maxSize, "w1");
+
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
+ l->setSpacing(0);
+ l->setContentsMargins(0, 0, 0, 0);
+
+ // horizontal and vertical
+ l->addAnchors(l, w1);
+
+ QGraphicsWidget *p = new QGraphicsWidget;
+ p->setLayout(l);
+
+ scene.addItem(p);
+ QGraphicsView *view = new QGraphicsView(&scene);
+
+ // QSizePolicy::Minimum
+ w1->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+ QApplication::processEvents();
+ w1->adjustSize();
+
+ QCOMPARE(l->effectiveSizeHint(Qt::MinimumSize), QSizeF(50, 50));
+ QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(50, 50));
+ QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(100, 100));
+
+ // QSizePolicy::Maximum
+ w1->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
+ QApplication::processEvents();
+ w1->adjustSize();
+
+ QCOMPARE(l->effectiveSizeHint(Qt::MinimumSize), QSizeF(0, 0));
+ QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(50, 50));
+ QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(50, 50));
+
+ // QSizePolicy::Fixed
+ w1->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ QApplication::processEvents();
+ w1->adjustSize();
+
+ QCOMPARE(l->effectiveSizeHint(Qt::MinimumSize), QSizeF(50, 50));
+ QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(50, 50));
+ QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(50, 50));
+
+ // QSizePolicy::Preferred
+ w1->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+ QApplication::processEvents();
+ w1->adjustSize();
+
+ QCOMPARE(l->effectiveSizeHint(Qt::MinimumSize), QSizeF(0, 0));
+ QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(50, 50));
+ QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(100, 100));
+
+ // QSizePolicy::Ignored
+ w1->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
+ QApplication::processEvents();
+ w1->adjustSize();
+
+ QCOMPARE(l->effectiveSizeHint(Qt::MinimumSize), QSizeF(0, 0));
+ QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(0, 0));
+ QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(100, 100));
+
+ // Anchor size policies
+ w1->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ QGraphicsAnchor *anchor = l->anchor(l, Qt::AnchorLeft, w1, Qt::AnchorLeft);
+ anchor->setSpacing(10);
+
+ // QSizePolicy::Minimum
+ anchor->setSizePolicy(QSizePolicy::Minimum);
+ QApplication::processEvents();
+
+ QCOMPARE(l->effectiveSizeHint(Qt::MinimumSize), QSizeF(60, 50));
+ QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(60, 50));
+ // The layout has a maximum size of QWIDGETSIZE_MAX, so the result won't exceed that value.
+ QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(QWIDGETSIZE_MAX, 50));
+
+ // QSizePolicy::Preferred
+ anchor->setSizePolicy(QSizePolicy::Preferred);
+ QApplication::processEvents();
+
+ QCOMPARE(l->effectiveSizeHint(Qt::MinimumSize), QSizeF(50, 50));
+ QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(60, 50));
+ // The layout has a maximum size of QWIDGETSIZE_MAX, so the result won't exceed that value.
+ QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(QWIDGETSIZE_MAX, 50));
+
+ // QSizePolicy::Maximum
+ anchor->setSizePolicy(QSizePolicy::Maximum);
+ QApplication::processEvents();
+
+ QCOMPARE(l->effectiveSizeHint(Qt::MinimumSize), QSizeF(50, 50));
+ QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(60, 50));
+ QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(60, 50));
+
+ // QSizePolicy::Ignored
+ anchor->setSizePolicy(QSizePolicy::Ignored);
+ QApplication::processEvents();
+
+ QCOMPARE(l->effectiveSizeHint(Qt::MinimumSize), QSizeF(50, 50));
+ QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(50, 50));
+ QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(QWIDGETSIZE_MAX, 50));
+
+ if (hasSimplification) {
+ QVERIFY(!usedSimplex(l, Qt::Horizontal));
+ QVERIFY(!usedSimplex(l, Qt::Vertical));
+ }
+
+ delete p;
+ delete view;
+}
+
+/*!
+ \internal
+
+ Uses private API. (We have decided to pull hasConflicts() out of the API). However, it also
+ tests some tight conditions (almost-in-conflict) that we really want to test.
+*/
+void tst_QGraphicsAnchorLayout::conflicts()
+{
+ QGraphicsWidget *a = createItem(QSizeF(80,10), QSizeF(90,10), QSizeF(100,10), "a");
+ QGraphicsWidget *b = createItem(QSizeF(10,10), QSizeF(20,10), QSizeF(30,10), "b");
+ QGraphicsWidget *c = createItem(QSizeF(10,10), QSizeF(20,10), QSizeF(30,10), "c");
+
+ QGraphicsAnchorLayout *l;
+ QGraphicsWidget *p = new QGraphicsWidget(0, Qt::Window);
+
+ l = new QGraphicsAnchorLayout;
+ l->setContentsMargins(0, 0, 0, 0);
+
+ // with the following setup, 'a' cannot be larger than 30 we will first have a Simplex conflict
+
+ // horizontal
+ setAnchor(l, l, Qt::AnchorLeft, b, Qt::AnchorLeft);
+ setAnchor(l, b, Qt::AnchorRight, c, Qt::AnchorLeft);
+ setAnchor(l, c, Qt::AnchorRight, l, Qt::AnchorRight);
+ setAnchor(l, b, Qt::AnchorHorizontalCenter, a, Qt::AnchorLeft);
+ setAnchor(l, a, Qt::AnchorRight, c, Qt::AnchorHorizontalCenter);
+
+ // vertical
+ setAnchor(l, l, Qt::AnchorTop, a, Qt::AnchorTop);
+ setAnchor(l, a, Qt::AnchorBottom, b, Qt::AnchorTop);
+ setAnchor(l, a, Qt::AnchorBottom, c, Qt::AnchorTop);
+ setAnchor(l, b, Qt::AnchorBottom, l, Qt::AnchorBottom);
+ setAnchor(l, c, Qt::AnchorBottom, l, Qt::AnchorBottom);
+
+ p->setLayout(l);
+
+ QCOMPARE(layoutHasConflict(l), true);
+
+ a->setMinimumSize(QSizeF(29,10));
+ QCOMPARE(layoutHasConflict(l), false);
+
+ a->setMinimumSize(QSizeF(30,10));
+ QCOMPARE(layoutHasConflict(l), false);
+
+ delete p;
+}
+
+void tst_QGraphicsAnchorLayout::floatConflict()
+{
+ QGraphicsWidget *a = createItem(QSizeF(80,10), QSizeF(90,10), QSizeF(100,10), "a");
+ QGraphicsWidget *b = createItem(QSizeF(80,10), QSizeF(90,10), QSizeF(100,10), "b");
+
+ QGraphicsAnchorLayout *l;
+ QGraphicsWidget *p = new QGraphicsWidget(0, Qt::Window);
+
+ l = new QGraphicsAnchorLayout;
+ l->setContentsMargins(0, 0, 0, 0);
+
+ p->setLayout(l);
+
+ // horizontal
+ // with this anchor we have two floating items
+ setAnchor(l, a, Qt::AnchorRight, b, Qt::AnchorLeft);
+
+ // Just checking if the layout is handling well the removal of floating items
+ delete l->anchor(a, Qt::AnchorRight, b, Qt::AnchorLeft);
+ QCOMPARE(l->count(), 0);
+ QCOMPARE(layoutHasConflict(l), false);
+
+ // setting back the same anchor
+ setAnchor(l, a, Qt::AnchorRight, b, Qt::AnchorLeft);
+
+ // We don't support floating items but they should be counted as if they are in the layout
+ QCOMPARE(l->count(), 2);
+ // Although, we have an invalid situation
+ QCOMPARE(layoutHasConflict(l), true);
+
+ // Semi-floats are supported
+ setAnchor(l, a, Qt::AnchorLeft, l, Qt::AnchorLeft);
+ QCOMPARE(l->count(), 2);
+
+ // Vertically the layout has floating items. Therefore, we have a conflict
+ QCOMPARE(layoutHasConflict(l), true);
+
+ // No more floating items
+ setAnchor(l, b, Qt::AnchorRight, l, Qt::AnchorRight);
+ setAnchor(l, a, Qt::AnchorTop, l, Qt::AnchorTop);
+ setAnchor(l, a, Qt::AnchorBottom, l, Qt::AnchorBottom);
+ setAnchor(l, b, Qt::AnchorTop, l, Qt::AnchorTop);
+ setAnchor(l, b, Qt::AnchorBottom, l, Qt::AnchorBottom);
+ QCOMPARE(layoutHasConflict(l), false);
+
+ delete p;
+}
+
+void tst_QGraphicsAnchorLayout::infiniteMaxSizes()
+{
+ if (sizeof(qreal) <= 4) {
+ QSKIP("qreal has too little precision, result will be wrong", SkipAll);
+ }
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
+ l->setContentsMargins(0, 0, 0, 0);
+ l->setSpacing(0);
+
+ QSizeF minSize(10, 10);
+ QSizeF pref(50, 10);
+ QSizeF maxSize(QWIDGETSIZE_MAX, 10);
+
+ QGraphicsWidget *a = createItem(minSize, pref, maxSize, "a");
+ QGraphicsWidget *b = createItem(minSize, pref, maxSize, "b");
+ QGraphicsWidget *c = createItem(minSize, pref, maxSize, "c");
+ QGraphicsWidget *d = createItem(minSize, pref, maxSize, "d");
+ QGraphicsWidget *e = createItem(minSize, pref, maxSize, "e");
+
+ //<!-- Trunk -->
+ setAnchor(l, l, Qt::AnchorLeft, a, Qt::AnchorLeft, 0);
+ setAnchor(l, a, Qt::AnchorRight, b, Qt::AnchorLeft, 0);
+ setAnchor(l, b, Qt::AnchorRight, c, Qt::AnchorLeft, 0);
+ setAnchor(l, c, Qt::AnchorRight, d, Qt::AnchorLeft, 0);
+ setAnchor(l, d, Qt::AnchorRight, l, Qt::AnchorRight, 0);
+ setAnchor(l, b, Qt::AnchorHorizontalCenter, e, Qt::AnchorLeft, 0);
+ setAnchor(l, e, Qt::AnchorRight, c, Qt::AnchorHorizontalCenter, 0);
+
+ QGraphicsWidget p;
+ p.setLayout(l);
+
+ QCOMPARE(int(p.effectiveSizeHint(Qt::MaximumSize).width()),
+ QWIDGETSIZE_MAX);
+
+ p.resize(200, 10);
+ QCOMPARE(a->geometry(), QRectF(0, 0, 50, 10));
+ QCOMPARE(b->geometry(), QRectF(50, 0, 50, 10));
+ QCOMPARE(c->geometry(), QRectF(100, 0, 50, 10));
+ QCOMPARE(d->geometry(), QRectF(150, 0, 50, 10));
+
+ p.resize(1000, 10);
+ QCOMPARE(a->geometry(), QRectF(0, 0, 250, 10));
+ QCOMPARE(b->geometry(), QRectF(250, 0, 250, 10));
+ QCOMPARE(c->geometry(), QRectF(500, 0, 250, 10));
+ QCOMPARE(d->geometry(), QRectF(750, 0, 250, 10));
+
+ p.resize(40000, 10);
+ QCOMPARE(a->geometry(), QRectF(0, 0, 10000, 10));
+ QCOMPARE(b->geometry(), QRectF(10000, 0, 10000, 10));
+ QCOMPARE(c->geometry(), QRectF(20000, 0, 10000, 10));
+ QCOMPARE(d->geometry(), QRectF(30000, 0, 10000, 10));
+}
+
+void tst_QGraphicsAnchorLayout::simplifiableUnfeasible()
+{
+ QGraphicsWidget *a = createItem(QSizeF(70.0, 100.0),
+ QSizeF(100.0, 100.0),
+ QSizeF(100.0, 100.0), "A");
+
+ QGraphicsWidget *b = createItem(QSizeF(110.0, 100.0),
+ QSizeF(150.0, 100.0),
+ QSizeF(190.0, 100.0), "B");
+
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
+ l->setContentsMargins(0, 0, 0, 0);
+ l->setSpacing(0);
+
+ l->addAnchor(l, Qt::AnchorTop, a, Qt::AnchorTop);
+ l->addAnchor(a, Qt::AnchorBottom, b, Qt::AnchorTop);
+ l->addAnchor(b, Qt::AnchorBottom, l, Qt::AnchorBottom);
+
+ l->addAnchors(l, a, Qt::Horizontal);
+ l->addAnchor(l, Qt::AnchorLeft, b, Qt::AnchorLeft);
+ l->addAnchor(b, Qt::AnchorRight, a, Qt::AnchorRight);
+
+ QCOMPARE(l->count(), 2);
+
+ QGraphicsWidget p;
+ p.setLayout(l);
+
+ l->invalidate();
+ QVERIFY(layoutHasConflict(l));
+ if (hasSimplification)
+ QVERIFY(!usedSimplex(l, Qt::Horizontal));
+
+ // Now we make it valid
+ b->setMinimumWidth(100);
+
+ l->invalidate();
+ QVERIFY(!layoutHasConflict(l));
+ if (hasSimplification)
+ QVERIFY(!usedSimplex(l, Qt::Horizontal));
+
+ // And make it invalid again
+ a->setPreferredWidth(70);
+ a->setMaximumWidth(70);
+
+ l->invalidate();
+ QVERIFY(layoutHasConflict(l));
+ if (hasSimplification)
+ QVERIFY(!usedSimplex(l, Qt::Horizontal));
+}
+
+/*
+ Test whether the anchor direction can prevent it from
+ being simplificated
+*/
+void tst_QGraphicsAnchorLayout::simplificationVsOrder()
+{
+ QSizeF minSize(10, 10);
+ QSizeF pref(20, 10);
+ QSizeF maxSize(50, 10);
+
+ QGraphicsWidget *a = createItem(minSize, pref, maxSize, "A");
+ QGraphicsWidget *b = createItem(minSize, pref, maxSize, "B");
+ QGraphicsWidget *c = createItem(minSize, pref, maxSize, "C");
+
+ QGraphicsWidget frame;
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout(&frame);
+
+ // Bulk anchors
+ l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft);
+ l->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorLeft);
+ l->addAnchor(b, Qt::AnchorLeft, c, Qt::AnchorLeft);
+ l->addAnchor(c, Qt::AnchorRight, l, Qt::AnchorRight);
+
+ // Problematic anchor, direction b->c
+ QGraphicsAnchor *anchor = l->addAnchor(b, Qt::AnchorRight, c, Qt::AnchorRight);
+ anchor->setSpacing(5);
+
+ l->effectiveSizeHint(Qt::MinimumSize);
+ if (hasSimplification) {
+ QCOMPARE(usedSimplex(l, Qt::Horizontal), false);
+ QCOMPARE(usedSimplex(l, Qt::Vertical), false);
+ }
+
+ // Problematic anchor, direction c->b
+ delete anchor;
+ anchor = l->addAnchor(c, Qt::AnchorRight, b, Qt::AnchorRight);
+ anchor->setSpacing(5);
+
+ l->effectiveSizeHint(Qt::MinimumSize);
+ if (hasSimplification) {
+ QCOMPARE(usedSimplex(l, Qt::Horizontal), false);
+ QCOMPARE(usedSimplex(l, Qt::Vertical), false);
+ }
+}
+
+void tst_QGraphicsAnchorLayout::parallelSimplificationOfCenter()
+{
+ QSizeF minSize(10, 10);
+ QSizeF pref(20, 10);
+ QSizeF maxSize(50, 10);
+
+ QGraphicsWidget *a = createItem(minSize, pref, maxSize, "A");
+ QGraphicsWidget *b = createItem(minSize, pref, maxSize, "B");
+
+ QGraphicsWidget parent;
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout(&parent);
+ l->setContentsMargins(0, 0, 0, 0);
+
+ l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft);
+ l->addAnchor(l, Qt::AnchorRight, a, Qt::AnchorRight);
+
+ l->addAnchor(a, Qt::AnchorHorizontalCenter, b, Qt::AnchorLeft);
+ l->addAnchor(b, Qt::AnchorRight, a, Qt::AnchorRight);
+
+ parent.resize(l->effectiveSizeHint(Qt::PreferredSize));
+
+ QCOMPARE(a->geometry(), QRectF(0, 0, 40, 10));
+ QCOMPARE(b->geometry(), QRectF(20, 0, 20, 10));
+}
+
+/*
+ Test whether redundance of anchors (in this case by using addCornerAnchors), will
+ prevent simplification to take place when it should.
+*/
+void tst_QGraphicsAnchorLayout::simplificationVsRedundance()
+{
+ QSizeF minSize(10, 10);
+ QSizeF pref(20, 10);
+ QSizeF maxSize(50, 30);
+
+ QGraphicsWidget *a = createItem(minSize, pref, maxSize, "A");
+ QGraphicsWidget *b = createItem(minSize, pref, maxSize, "B");
+ QGraphicsWidget *c = createItem(minSize, pref, maxSize, "C");
+
+ QGraphicsWidget frame;
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout(&frame);
+
+ l->addCornerAnchors(a, Qt::TopLeftCorner, l, Qt::TopLeftCorner);
+ l->addCornerAnchors(a, Qt::BottomLeftCorner, l, Qt::BottomLeftCorner);
+
+ l->addCornerAnchors(b, Qt::TopLeftCorner, a, Qt::TopRightCorner);
+ l->addCornerAnchors(b, Qt::TopRightCorner, l, Qt::TopRightCorner);
+
+ l->addCornerAnchors(c, Qt::TopLeftCorner, b, Qt::BottomLeftCorner);
+ l->addCornerAnchors(c, Qt::BottomLeftCorner, a, Qt::BottomRightCorner);
+ l->addCornerAnchors(c, Qt::TopRightCorner, b, Qt::BottomRightCorner);
+ l->addCornerAnchors(c, Qt::BottomRightCorner, l, Qt::BottomRightCorner);
+
+ l->effectiveSizeHint(Qt::MinimumSize);
+
+ QCOMPARE(layoutHasConflict(l), false);
+
+ if (!hasSimplification)
+ QEXPECT_FAIL("", "Test depends on simplification.", Abort);
+
+ QCOMPARE(usedSimplex(l, Qt::Horizontal), false);
+ QCOMPARE(usedSimplex(l, Qt::Vertical), false);
+}
+
+/*
+ Avoid regression where the saved prefSize would be lost. This was
+ solved by saving the original spacing in the QGraphicsAnchorPrivate class
+*/
+void tst_QGraphicsAnchorLayout::spacingPersistency()
+{
+ QGraphicsWidget w;
+ QGraphicsWidget *a = createItem();
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout(&w);
+
+ l->addAnchors(l, a, Qt::Horizontal);
+ QGraphicsAnchor *anchor = l->anchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft);
+
+ anchor->setSpacing(-30);
+ QCOMPARE(anchor->spacing(), -30.0);
+
+ anchor->setSpacing(30);
+ QCOMPARE(anchor->spacing(), 30.0);
+
+ anchor->setSizePolicy(QSizePolicy::Ignored);
+ w.effectiveSizeHint(Qt::PreferredSize);
+
+ QCOMPARE(anchor->spacing(), 30.0);
+}
+
+/*
+ Test whether a correct preferred size is set when a "snake" sequence is in parallel with the
+ layout or half of the layout. The tricky thing here is that all items on the snake should
+ keep their preferred sizes.
+*/
+void tst_QGraphicsAnchorLayout::snakeParallelWithLayout()
+{
+ QSizeF minSize(10, 20);
+ QSizeF pref(50, 20);
+ QSizeF maxSize(100, 20);
+
+ QGraphicsWidget *a = createItem(maxSize, maxSize, maxSize, "A");
+ QGraphicsWidget *b = createItem(minSize, pref, maxSize, "B");
+ QGraphicsWidget *c = createItem(maxSize, maxSize, maxSize, "C");
+
+ QGraphicsWidget parent;
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout(&parent);
+ l->setContentsMargins(0, 0, 0, 0);
+ l->setSpacing(0);
+
+ // First we'll do the case in parallel with the entire layout...
+ l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft);
+ l->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorRight);
+ l->addAnchor(b, Qt::AnchorLeft, c, Qt::AnchorLeft);
+ l->addAnchor(c, Qt::AnchorRight, l, Qt::AnchorRight);
+
+ l->addAnchor(l, Qt::AnchorTop, a, Qt::AnchorTop);
+ l->addAnchor(a, Qt::AnchorBottom, b, Qt::AnchorTop);
+ l->addAnchor(b, Qt::AnchorBottom, c, Qt::AnchorTop);
+ l->addAnchor(c, Qt::AnchorBottom, l, Qt::AnchorBottom);
+
+ parent.resize(l->effectiveSizeHint(Qt::PreferredSize));
+
+ // Note that A and C are fixed in the maximum size
+ QCOMPARE(l->geometry(), QRectF(QPointF(0, 0), QSizeF(150, 60)));
+ QCOMPARE(a->geometry(), QRectF(QPointF(0, 0), maxSize));
+ QCOMPARE(b->geometry(), QRectF(QPointF(50, 20), pref));
+ QCOMPARE(c->geometry(), QRectF(QPointF(50, 40), maxSize));
+
+ // Then, we change the "snake" to be in parallel with half of the layout
+ delete l->anchor(c, Qt::AnchorRight, l, Qt::AnchorRight);
+ l->addAnchor(c, Qt::AnchorRight, l, Qt::AnchorHorizontalCenter);
+
+ parent.resize(l->effectiveSizeHint(Qt::PreferredSize));
+
+ QCOMPARE(l->geometry(), QRectF(QPointF(0, 0), QSizeF(300, 60)));
+ QCOMPARE(a->geometry(), QRectF(QPointF(0, 0), maxSize));
+ QCOMPARE(b->geometry(), QRectF(QPointF(50, 20), pref));
+ QCOMPARE(c->geometry(), QRectF(QPointF(50, 40), maxSize));
+}
+
+/*
+ Avoid regression where the sizeHint constraints would not be
+ created for a parallel anchor that included the first layout half
+*/
+void tst_QGraphicsAnchorLayout::parallelToHalfLayout()
+{
+ QGraphicsWidget *a = createItem();
+
+ QGraphicsWidget w;
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout(&w);
+ l->setContentsMargins(10, 10, 10, 10);
+
+ l->addAnchors(l, a, Qt::Vertical);
+
+ QGraphicsAnchor *anchor;
+ anchor = l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft);
+ anchor->setSpacing(5);
+ anchor = l->addAnchor(l, Qt::AnchorHorizontalCenter, a, Qt::AnchorRight);
+ anchor->setSpacing(-5);
+
+ const QSizeF minimumSizeHint = w.effectiveSizeHint(Qt::MinimumSize);
+ const QSizeF preferredSizeHint = w.effectiveSizeHint(Qt::PreferredSize);
+ const QSizeF maximumSizeHint = w.effectiveSizeHint(Qt::MaximumSize);
+
+ const QSizeF overhead = QSizeF(10 + 5 + 5, 10) * 2;
+
+ QCOMPARE(minimumSizeHint, QSizeF(200, 100) + overhead);
+ QCOMPARE(preferredSizeHint, QSizeF(300, 100) + overhead);
+ QCOMPARE(maximumSizeHint, QSizeF(400, 100) + overhead);
+}
+
+void tst_QGraphicsAnchorLayout::globalSpacing()
+{
+ QGraphicsWidget *a = createItem();
+ QGraphicsWidget *b = createItem();
+
+ QGraphicsWidget w;
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout(&w);
+
+ l->addCornerAnchors(l, Qt::TopLeftCorner, a, Qt::TopLeftCorner);
+ l->addCornerAnchors(a, Qt::BottomRightCorner, b, Qt::TopLeftCorner);
+ l->addCornerAnchors(b, Qt::BottomRightCorner, l, Qt::BottomRightCorner);
+
+ w.resize(w.effectiveSizeHint(Qt::PreferredSize));
+ qreal vSpacing = b->geometry().top() - a->geometry().bottom();
+ qreal hSpacing = b->geometry().left() - a->geometry().right();
+
+ // Set spacings manually
+ l->setVerticalSpacing(vSpacing + 10);
+ l->setHorizontalSpacing(hSpacing + 5);
+
+ w.resize(w.effectiveSizeHint(Qt::PreferredSize));
+ qreal newVSpacing = b->geometry().top() - a->geometry().bottom();
+ qreal newHSpacing = b->geometry().left() - a->geometry().right();
+
+ QCOMPARE(newVSpacing, vSpacing + 10);
+ QCOMPARE(newHSpacing, hSpacing + 5);
+
+ // Set a negative spacing. This will unset the previous spacing and
+ // bring back the widget-defined spacing.
+ l->setSpacing(-1);
+
+ w.resize(w.effectiveSizeHint(Qt::PreferredSize));
+ newVSpacing = b->geometry().top() - a->geometry().bottom();
+ newHSpacing = b->geometry().left() - a->geometry().right();
+
+ QCOMPARE(newVSpacing, vSpacing);
+ QCOMPARE(newHSpacing, hSpacing);
+}
+
+void tst_QGraphicsAnchorLayout::graphicsAnchorHandling()
+{
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout();
+ QGraphicsWidget *a = createItem();
+
+ l->addAnchors(l, a);
+
+ QGraphicsAnchor *layoutAnchor = l->anchor(l, Qt::AnchorTop, l, Qt::AnchorBottom);
+ QGraphicsAnchor *itemAnchor = l->anchor(a, Qt::AnchorTop, a, Qt::AnchorBottom);
+ QGraphicsAnchor *invalidAnchor = l->anchor(a, Qt::AnchorTop, l, Qt::AnchorBottom);
+
+ // Ensure none of these anchors are accessible.
+ QVERIFY(layoutAnchor == 0);
+ QVERIFY(itemAnchor == 0);
+ QVERIFY(invalidAnchor == 0);
+
+ // Hook the anchors to a QObject
+ QObject object;
+ QGraphicsAnchor *userAnchor = l->anchor(l, Qt::AnchorTop, a, Qt::AnchorTop);
+ userAnchor->setParent(&object);
+ userAnchor = l->anchor(l, Qt::AnchorBottom, a, Qt::AnchorBottom);
+ userAnchor->setParent(&object);
+ userAnchor = l->anchor(l, Qt::AnchorRight, a, Qt::AnchorRight);
+ userAnchor->setParent(&object);
+ userAnchor = l->anchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft);
+ userAnchor->setParent(&object);
+
+ QCOMPARE(object.children().size(), 4);
+
+ // Delete layout, this will cause all anchors to be deleted internally.
+ // We expect the public QGraphicsAnchor instances to be deleted too.
+ delete l;
+ QCOMPARE(object.children().size(), 0);
+
+ delete a;
+}
+
+void tst_QGraphicsAnchorLayout::invalidHierarchyCheck()
+{
+ QGraphicsWidget window(0, Qt::Window);
+ QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
+ window.setLayout(l);
+
+ QCOMPARE(l->count(), 0);
+ QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): "
+ "You cannot add the parent of the layout to the layout.");
+ QVERIFY(!l->addAnchor(l, Qt::AnchorLeft, &window, Qt::AnchorLeft));
+ QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): "
+ "You cannot add the parent of the layout to the layout.");
+ l->addAnchors(l, &window);
+ QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): "
+ "You cannot add the parent of the layout to the layout.");
+ l->addCornerAnchors(l, Qt::TopLeftCorner, &window, Qt::TopLeftCorner);
+ QCOMPARE(l->count(), 0);
+}
+
+QTEST_MAIN(tst_QGraphicsAnchorLayout)
+#include "tst_qgraphicsanchorlayout.moc"
diff --git a/tests/auto/widgets/graphicsview/qgraphicsanchorlayout1/qgraphicsanchorlayout1.pro b/tests/auto/widgets/graphicsview/qgraphicsanchorlayout1/qgraphicsanchorlayout1.pro
new file mode 100644
index 0000000000..bcad43fc12
--- /dev/null
+++ b/tests/auto/widgets/graphicsview/qgraphicsanchorlayout1/qgraphicsanchorlayout1.pro
@@ -0,0 +1,5 @@
+load(qttest_p4)
+QT += widgets widgets-private
+QT += core-private gui-private
+SOURCES += tst_qgraphicsanchorlayout1.cpp
+CONFIG += parallel_test
diff --git a/tests/auto/widgets/graphicsview/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp b/tests/auto/widgets/graphicsview/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp
new file mode 100644
index 0000000000..05f08e8719
--- /dev/null
+++ b/tests/auto/widgets/graphicsview/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp
@@ -0,0 +1,3111 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+#include <QtTest/QtTest>
+#include <QTest>
+#include <QMetaType>
+#include <QtWidgets/qgraphicsanchorlayout.h>
+#include <private/qgraphicsanchorlayout_p.h>
+
+#define TEST_COMPLEX_CASES
+
+
+//---------------------- AnchorLayout helper class ----------------------------
+class TheAnchorLayout : public QGraphicsAnchorLayout
+{
+public:
+ TheAnchorLayout() : QGraphicsAnchorLayout()
+ {
+ setContentsMargins( 0,0,0,0 );
+ setSpacing( 0 );
+ }
+
+ bool isValid()
+ {
+ return !QGraphicsAnchorLayoutPrivate::get(this)->hasConflicts();
+ }
+
+ void setAnchor(
+ QGraphicsLayoutItem *startItem,
+ Qt::AnchorPoint startEdge,
+ QGraphicsLayoutItem *endItem,
+ Qt::AnchorPoint endEdge,
+ qreal value)
+ {
+ QGraphicsAnchor *anchor = addAnchor( startItem, startEdge, endItem, endEdge);
+ if (anchor)
+ anchor->setSpacing(value);
+ }
+
+ int indexOf(const QGraphicsLayoutItem* item) const
+ {
+ for ( int i=0; i< count(); i++) {
+ if ( itemAt(i) == item ) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ void removeItem(QGraphicsLayoutItem* item)
+ {
+ removeAt(indexOf(item));
+ }
+
+ void removeAnchor(
+ QGraphicsLayoutItem *startItem,
+ Qt::AnchorPoint startEdge,
+ QGraphicsLayoutItem *endItem,
+ Qt::AnchorPoint endEdge)
+ {
+ delete QGraphicsAnchorLayout::anchor(startItem, startEdge, endItem, endEdge);
+ }
+};
+//-----------------------------------------------------------------------------
+
+
+struct BasicLayoutTestData
+{
+ inline BasicLayoutTestData(
+ int index1, Qt::AnchorPoint edge1,
+ int index2, Qt::AnchorPoint edge2,
+ qreal distance)
+ : firstIndex(index1), firstEdge(edge1),
+ secondIndex(index2), secondEdge(edge2),
+ spacing(distance)
+ {
+ }
+
+ int firstIndex;
+ Qt::AnchorPoint firstEdge;
+ int secondIndex;
+ Qt::AnchorPoint secondEdge;
+ qreal spacing;
+};
+
+struct AnchorItemSizeHint
+{
+ inline AnchorItemSizeHint(
+ qreal hmin, qreal hpref, qreal hmax,
+ qreal vmin, qreal vpref, qreal vmax )
+ : hmin(hmin), hpref(hpref), hmax(hmax), vmin(vmin), vpref(vpref), vmax(vmax)
+ {
+ }
+ qreal hmin, hpref, hmax;
+ qreal vmin, vpref, vmax;
+};
+
+// some test results
+
+struct BasicLayoutTestResult
+{
+ inline BasicLayoutTestResult(
+ int resultIndex, const QRectF& resultRect )
+ : index(resultIndex), rect(resultRect)
+ {
+ }
+
+ int index;
+ QRectF rect;
+};
+
+typedef QList<BasicLayoutTestData> BasicLayoutTestDataList;
+Q_DECLARE_METATYPE(BasicLayoutTestDataList)
+
+typedef QList<BasicLayoutTestResult> BasicLayoutTestResultList;
+Q_DECLARE_METATYPE(BasicLayoutTestResultList)
+
+typedef QList<AnchorItemSizeHint> AnchorItemSizeHintList;
+Q_DECLARE_METATYPE(AnchorItemSizeHintList)
+
+
+//---------------------- Test Widget used on all tests ------------------------
+class TestWidget : public QGraphicsWidget
+{
+public:
+ inline TestWidget(QGraphicsItem *parent = 0, const QString &name = QString())
+ : QGraphicsWidget(parent)
+ {
+ setContentsMargins( 0,0,0,0 );
+ if (name.isEmpty())
+ setData(0, QString::fromAscii("w%1").arg(quintptr(this)));
+ else
+ setData(0, name);
+ }
+ ~TestWidget()
+ {
+ }
+
+protected:
+ QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
+};
+
+QSizeF TestWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
+{
+ Q_UNUSED( constraint );
+ if (which == Qt::MinimumSize) {
+ return QSizeF(5,5);
+ }
+
+ if (which == Qt::PreferredSize) {
+ return QSizeF(50,50);
+ }
+
+ return QSizeF(500,500);
+}
+//-----------------------------------------------------------------------------
+
+
+
+//----------------------------- Test class ------------------------------------
+class tst_QGraphicsAnchorLayout1 : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void testCount();
+
+ void testRemoveAt();
+ void testRemoveItem();
+
+ void testItemAt();
+ void testIndexOf();
+
+ void testAddAndRemoveAnchor();
+ void testIsValid();
+ void testSpecialCases();
+
+ void testBasicLayout_data();
+ void testBasicLayout();
+
+ void testNegativeSpacing_data();
+ void testNegativeSpacing();
+
+ void testMixedSpacing_data();
+ void testMixedSpacing();
+
+ void testMulti_data();
+ void testMulti();
+
+ void testCenterAnchors_data();
+ void testCenterAnchors();
+
+ void testRemoveCenterAnchor_data();
+ void testRemoveCenterAnchor();
+
+ void testSingleSizePolicy_data();
+ void testSingleSizePolicy();
+
+ void testDoubleSizePolicy_data();
+ void testDoubleSizePolicy();
+
+ void testSizeDistribution_data();
+ void testSizeDistribution();
+
+ void testSizeHint();
+
+#ifdef TEST_COMPLEX_CASES
+ void testComplexCases_data();
+ void testComplexCases();
+#endif
+};
+
+
+void tst_QGraphicsAnchorLayout1::testCount()
+{
+ QGraphicsWidget *widget = new QGraphicsWidget;
+
+ TheAnchorLayout *layout = new TheAnchorLayout();
+ QVERIFY( layout->count() == 0 );
+
+ TestWidget *widget1 = new TestWidget();
+ layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
+ QCOMPARE( layout->count(), 1 );
+
+ // adding one more anchor for already added widget should not increase the count
+ layout->setAnchor(layout, Qt::AnchorRight, widget1, Qt::AnchorRight, 1);
+ QCOMPARE( layout->count(), 1 );
+
+ // create one more widget and attach with anchor layout
+ TestWidget *widget2 = new TestWidget();
+ layout->setAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 1);
+ QCOMPARE( layout->count(), 2 );
+
+ widget->setLayout(layout);
+ delete widget;
+}
+
+void tst_QGraphicsAnchorLayout1::testRemoveAt()
+{
+ TheAnchorLayout *layout = new TheAnchorLayout();
+ QVERIFY( layout->count() == 0 );
+
+ TestWidget *widget1 = new TestWidget();
+ layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 2);
+ QVERIFY( layout->count() == 1 );
+
+ TestWidget *widget2 = new TestWidget();
+ layout->setAnchor(widget2, Qt::AnchorLeft, layout, Qt::AnchorLeft, 0.1);
+ QVERIFY( layout->count() == 2 );
+
+ layout->removeAt(0);
+ QVERIFY( layout->count() == 1 );
+
+ layout->removeAt(-55);
+ layout->removeAt(55);
+ QVERIFY( layout->count() == 1 );
+
+ layout->removeAt(0);
+ QVERIFY( layout->count() == 0 );
+
+ delete layout;
+ delete widget1;
+ delete widget2;
+}
+
+void tst_QGraphicsAnchorLayout1::testRemoveItem()
+{
+ TheAnchorLayout *layout = new TheAnchorLayout();
+ QCOMPARE( layout->count(), 0 );
+
+ TestWidget *widget1 = new TestWidget();
+ layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 2);
+ QCOMPARE( layout->count(), 1 );
+
+ TestWidget *widget2 = new TestWidget();
+ layout->setAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 0.1);
+ QCOMPARE( layout->count(), 2 );
+
+ layout->removeItem(0);
+ QCOMPARE( layout->count(), 2 );
+
+ layout->removeItem(widget1);
+ QCOMPARE( layout->count(), 1 );
+ QCOMPARE( layout->indexOf(widget1), -1 );
+ QCOMPARE( layout->indexOf(widget2), 0 );
+
+ layout->removeItem(widget1);
+ QCOMPARE( layout->count(), 1 );
+
+ layout->removeItem(widget2);
+ QVERIFY( layout->count() == 0 );
+
+ delete layout;
+ delete widget1;
+ delete widget2;
+}
+
+void tst_QGraphicsAnchorLayout1::testItemAt()
+{
+ QGraphicsWidget *widget = new QGraphicsWidget;
+
+ TheAnchorLayout *layout = new TheAnchorLayout();
+
+ TestWidget *widget1 = new TestWidget();
+ TestWidget *widget2 = new TestWidget();
+ TestWidget *widget3 = new TestWidget();
+ TestWidget *widget4 = new TestWidget();
+
+ layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1);
+ layout->setAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 0.1);
+ layout->setAnchor(layout, Qt::AnchorLeft, widget3, Qt::AnchorLeft, 0.1);
+ layout->setAnchor(layout, Qt::AnchorLeft, widget4, Qt::AnchorLeft, 0.1);
+
+ QVERIFY( layout->itemAt(0) == widget1 );
+
+ layout->removeAt(0);
+
+ QVERIFY( layout->itemAt(0) == widget2 );
+
+ delete widget1;
+
+ widget->setLayout(layout);
+ delete widget;
+}
+
+void tst_QGraphicsAnchorLayout1::testIndexOf()
+{
+ QGraphicsWidget *widget = new QGraphicsWidget;
+
+ TheAnchorLayout *layout = new TheAnchorLayout();
+
+ TestWidget *widget1 = new TestWidget();
+ TestWidget *widget2 = new TestWidget();
+ TestWidget *widget3 = new TestWidget();
+ TestWidget *widget4 = new TestWidget();
+
+ QCOMPARE( layout->indexOf(widget1), -1 );
+
+ layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1);
+ layout->setAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 0.1);
+ layout->setAnchor(layout, Qt::AnchorLeft, widget3, Qt::AnchorLeft, 0.1);
+
+ QCOMPARE( layout->indexOf(widget4), -1 );
+ layout->setAnchor(layout, Qt::AnchorLeft, widget4, Qt::AnchorLeft, 0.1);
+
+ QCOMPARE( layout->count(), 4 );
+ for (int i = 0; i < layout->count(); ++i) {
+ QCOMPARE(layout->indexOf(layout->itemAt(i)), i);
+ }
+
+ QCOMPARE( layout->indexOf(0), -1 );
+ widget->setLayout(layout);
+ delete widget;
+}
+
+void tst_QGraphicsAnchorLayout1::testAddAndRemoveAnchor()
+{
+ QGraphicsWidget *widget = new QGraphicsWidget;
+
+ TheAnchorLayout *layout = new TheAnchorLayout();
+
+ TestWidget *widget1 = new TestWidget();
+ TestWidget *widget2 = new TestWidget();
+ TestWidget *widget3 = new TestWidget();
+ TestWidget *widget4 = new TestWidget();
+ TestWidget *widget5 = new TestWidget();
+
+ layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1);
+ layout->setAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 0.5);
+ layout->setAnchor(layout, Qt::AnchorLeft, widget3, Qt::AnchorLeft, 10);
+ layout->setAnchor(layout, Qt::AnchorLeft, widget4, Qt::AnchorLeft, 0.1);
+ QCOMPARE( layout->count(), 4 );
+
+ // test setting invalid anchors
+ QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor NULL items");
+ layout->setAnchor(0, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
+ QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor NULL items");
+ layout->setAnchor(layout, Qt::AnchorLeft, 0, Qt::AnchorLeft, 1);
+ QCOMPARE( layout->count(), 4 );
+
+ // test removing invalid anchors
+ layout->removeAnchor(widget4, Qt::AnchorRight, widget1, Qt::AnchorRight);
+
+ // anchor one horizontal edge with vertical edge. it should not add this widget as a child
+ QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor edges of different orientations");
+ layout->setAnchor(layout, Qt::AnchorLeft, widget5, Qt::AnchorTop, 10);
+ QCOMPARE( layout->count(), 4 );
+
+ // anchor two edges of a widget (to define width / height)
+ QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
+ layout->setAnchor(widget5, Qt::AnchorLeft, widget5, Qt::AnchorRight, 10);
+ // QCOMPARE( layout->count(), 5 );
+ QCOMPARE( layout->count(), 4 );
+
+ // anchor yet new widget properly
+ layout->setAnchor(layout, Qt::AnchorRight, widget5, Qt::AnchorRight, 20 );
+ QCOMPARE( layout->count(), 5 );
+
+ // remove anchor for widget1. widget1 should be removed from layout since the
+ // last anchor was removed.
+ layout->removeAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft);
+
+ QCOMPARE( layout->count(), 4 );
+ QVERIFY( !widget1->parentLayoutItem() );
+
+ // test that item is not removed from layout if other anchors remain set
+ layout->setAnchor(widget2, Qt::AnchorLeft, widget3, Qt::AnchorRight, 10);
+ layout->removeAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft);
+ QCOMPARE( layout->count(), 4 );
+
+ // remove all the anchors
+ layout->removeAnchor(widget2, Qt::AnchorLeft, widget3, Qt::AnchorRight);
+ layout->removeAnchor(layout, Qt::AnchorLeft, widget3, Qt::AnchorLeft);
+ layout->removeAnchor(layout, Qt::AnchorLeft, widget4, Qt::AnchorLeft);
+ layout->removeAnchor(widget5, Qt::AnchorLeft, widget5, Qt::AnchorRight);
+ layout->removeAnchor(layout, Qt::AnchorRight, widget5, Qt::AnchorRight);
+
+ QCOMPARE( layout->count(), 0 );
+
+ // set one anchor "another way round" to get full coverage for "removeAnchor"
+ layout->setAnchor(widget1, Qt::AnchorLeft, layout, Qt::AnchorLeft, 0.1);
+ layout->removeAnchor(widget1, Qt::AnchorLeft, layout, Qt::AnchorLeft);
+
+ QCOMPARE( layout->count(), 0 );
+
+ delete widget1;
+ delete widget2;
+ delete widget3;
+ delete widget4;
+ delete widget5;
+
+ widget->setLayout(layout);
+ delete widget;
+}
+
+void tst_QGraphicsAnchorLayout1::testIsValid()
+{
+ // Empty, valid
+ {
+ QGraphicsWidget *widget = new QGraphicsWidget;
+ TheAnchorLayout *layout = new TheAnchorLayout();
+ widget->setLayout(layout);
+ widget->setGeometry(QRectF(0,0,100,100));
+
+ QCOMPARE(layout->isValid(), true);
+ delete widget;
+ }
+
+ // One widget, valid
+ {
+ QGraphicsWidget *widget = new QGraphicsWidget;
+ TheAnchorLayout *layout = new TheAnchorLayout();
+
+ TestWidget *widget1 = new TestWidget();
+
+ layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1);
+ layout->setAnchor(layout, Qt::AnchorTop, widget1, Qt::AnchorTop, 0.1);
+ layout->setAnchor(widget1, Qt::AnchorRight, layout, Qt::AnchorRight, 0.1);
+ layout->setAnchor(widget1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 0.1);
+
+ widget->setLayout(layout);
+
+ widget->setGeometry(QRectF(0,0,100,100));
+ QCOMPARE(layout->isValid(), true);
+ delete widget;
+ }
+
+ // Overconstrained one widget, invalid
+ // ### Our understanding is that this case is valid. What happens though,
+ // is that the layout minimum and maximum vertical size hints become
+ // the same, 10.1. That means its height is fixed.
+ // What will "fail" then is the "setGeometry(0, 0, 100, 100)" call,
+ // after which the layout geometry will be (0, 0, 100, 10.1).
+
+ {
+ QGraphicsWidget *widget = new QGraphicsWidget;
+ TheAnchorLayout *layout = new TheAnchorLayout();
+
+ TestWidget *widget1 = new TestWidget();
+
+ layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1);
+ layout->setAnchor(layout, Qt::AnchorTop, widget1, Qt::AnchorTop, 0.1);
+ layout->setAnchor(widget1, Qt::AnchorRight, layout, Qt::AnchorRight, 0.1);
+ layout->setAnchor(widget1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 0.1);
+
+ layout->setAnchor(widget1, Qt::AnchorTop, layout, Qt::AnchorBottom, 10);
+
+ widget->setLayout(layout);
+
+ widget->setGeometry(QRectF(0,0,100,100));
+ QCOMPARE(layout->isValid(), true);
+ delete widget;
+ }
+
+ // Underconstrained two widgets, valid
+ {
+ QGraphicsWidget *widget = new QGraphicsWidget;
+ TheAnchorLayout *layout = new TheAnchorLayout();
+
+ TestWidget *widget1 = new TestWidget();
+ TestWidget *widget2 = new TestWidget();
+
+ // Vertically the layout has floating items. Therefore, we have a conflict
+ layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1);
+ layout->setAnchor(layout, Qt::AnchorRight, widget1, Qt::AnchorRight, -0.1);
+
+ // Horizontally the layout has floating items. Therefore, we have a conflict
+ layout->setAnchor(layout, Qt::AnchorTop, widget2, Qt::AnchorTop, 0.1);
+ layout->setAnchor(layout, Qt::AnchorBottom, widget2, Qt::AnchorBottom, -0.1);
+
+ widget->setLayout(layout);
+
+ widget->setGeometry(QRectF(0,0,100,100));
+ QCOMPARE(layout->isValid(), false);
+ delete widget;
+ }
+}
+
+void tst_QGraphicsAnchorLayout1::testSpecialCases()
+{
+ // One widget, setLayout before defining layouts
+ {
+#ifdef QT_DEBUG
+ QTest::ignoreMessage(QtWarningMsg, "QGraphicsLayout::addChildLayoutItem: QGraphicsWidget \"\""
+ " in wrong parent; moved to correct parent");
+#endif
+ QGraphicsWidget *widget = new QGraphicsWidget;
+ TheAnchorLayout *layout = new TheAnchorLayout();
+ widget->setLayout(layout);
+
+ TestWidget *widget1 = new TestWidget();
+
+ layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
+ layout->setAnchor(layout, Qt::AnchorTop, widget1, Qt::AnchorTop, 1);
+ layout->setAnchor(widget1, Qt::AnchorRight, layout, Qt::AnchorRight, 1);
+ layout->setAnchor(widget1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
+ widget->setGeometry(QRectF(0,0,100,100));
+ QCOMPARE(widget1->geometry(), QRectF(1,1,98,98));
+ delete widget1;
+ delete widget;
+ }
+
+ // One widget, layout inside layout, layout inside layout inside layout
+ {
+#ifdef QT_DEBUG
+ QTest::ignoreMessage(QtWarningMsg, "QGraphicsLayout::addChildLayoutItem: QGraphicsWidget \"\""
+ " in wrong parent; moved to correct parent");
+#endif
+ QGraphicsWidget *widget = new QGraphicsWidget;
+ TheAnchorLayout *layout = new TheAnchorLayout();
+ widget->setLayout(layout);
+
+ TheAnchorLayout *layout1 = new TheAnchorLayout();
+ TestWidget *widget1 = new TestWidget();
+ layout1->setAnchor(layout1, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
+ layout1->setAnchor(layout1, Qt::AnchorTop, widget1, Qt::AnchorTop, 1);
+ layout1->setAnchor(widget1, Qt::AnchorRight, layout1, Qt::AnchorRight, 1);
+ layout1->setAnchor(widget1, Qt::AnchorBottom, layout1, Qt::AnchorBottom, 1);
+
+ TheAnchorLayout *layout2 = new TheAnchorLayout();
+ TestWidget *widget2 = new TestWidget();
+ layout2->setAnchor(layout2, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 1);
+ layout2->setAnchor(layout2, Qt::AnchorTop, widget2, Qt::AnchorTop, 1);
+ layout2->setAnchor(widget2, Qt::AnchorRight, layout2, Qt::AnchorRight, 1);
+ layout2->setAnchor(widget2, Qt::AnchorBottom, layout2, Qt::AnchorBottom, 1);
+
+ layout1->setAnchor(layout1, Qt::AnchorLeft, layout2, Qt::AnchorLeft, 1);
+ layout1->setAnchor(layout1, Qt::AnchorTop, layout2, Qt::AnchorTop, 1);
+ layout1->setAnchor(layout2, Qt::AnchorRight, layout1, Qt::AnchorRight, 1);
+ layout1->setAnchor(layout2, Qt::AnchorBottom, layout1, Qt::AnchorBottom, 1);
+
+ layout->setAnchor(layout, Qt::AnchorLeft, layout1, Qt::AnchorLeft, 1);
+ layout->setAnchor(layout, Qt::AnchorTop, layout1, Qt::AnchorTop, 1);
+ layout->setAnchor(layout1, Qt::AnchorRight, layout, Qt::AnchorRight, 1);
+ layout->setAnchor(layout1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
+
+ // remove and add again to improve test coverage.
+ layout->removeItem(layout1);
+
+ layout->setAnchor(layout, Qt::AnchorLeft, layout1, Qt::AnchorLeft, 1);
+ layout->setAnchor(layout, Qt::AnchorTop, layout1, Qt::AnchorTop, 1);
+ layout->setAnchor(layout1, Qt::AnchorRight, layout, Qt::AnchorRight, 1);
+ layout->setAnchor(layout1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
+
+ widget->setGeometry(QRectF(0,0,100,100));
+ QCOMPARE(widget1->geometry(), QRectF(2,2,96,96));
+ QCOMPARE(widget2->geometry(), QRectF(3,3,94,94));
+ delete widget;
+ }
+
+ // One widget, layout inside layout, setLayout after layout definition
+ {
+ QGraphicsWidget *widget = new QGraphicsWidget;
+ TheAnchorLayout *layout = new TheAnchorLayout();
+
+ TheAnchorLayout *layout1 = new TheAnchorLayout();
+
+ TestWidget *widget1 = new TestWidget();
+ layout1->setAnchor(layout1, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
+ layout1->setAnchor(layout1, Qt::AnchorTop, widget1, Qt::AnchorTop, 1);
+ layout1->setAnchor(widget1, Qt::AnchorRight, layout1, Qt::AnchorRight, 1);
+ layout1->setAnchor(widget1, Qt::AnchorBottom, layout1, Qt::AnchorBottom, 1);
+
+ layout->setAnchor(layout, Qt::AnchorLeft, layout1, Qt::AnchorLeft, 1);
+ layout->setAnchor(layout, Qt::AnchorTop, layout1, Qt::AnchorTop, 1);
+ layout->setAnchor(layout1, Qt::AnchorRight, layout, Qt::AnchorRight, 1);
+ layout->setAnchor(layout1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
+
+ widget->setLayout(layout);
+ widget->setGeometry(QRectF(0,0,100,100));
+ QCOMPARE(widget1->geometry(), QRectF(2,2,96,96));
+ delete widget;
+ }
+
+ // One widget, layout inside layout, setLayout after layout definition, widget transferred from
+ // one layout to another
+ {
+ QGraphicsWidget *widget = new QGraphicsWidget;
+ TheAnchorLayout *layout = new TheAnchorLayout();
+ widget->setLayout(layout);
+
+ TheAnchorLayout *layout1 = new TheAnchorLayout();
+ TestWidget *widget1 = new TestWidget();
+
+ // Additional layout + widget to improve coverage.
+ TheAnchorLayout *layout0 = new TheAnchorLayout();
+ TestWidget *widget0 = new TestWidget();
+
+ // widget0 to layout0
+ layout0->setAnchor(layout0, Qt::AnchorLeft, widget0, Qt::AnchorLeft, 1);
+ layout0->setAnchor(layout0, Qt::AnchorTop, widget0, Qt::AnchorTop, 1);
+ layout0->setAnchor(widget0, Qt::AnchorRight, layout0, Qt::AnchorRight, 1);
+ layout0->setAnchor(widget0, Qt::AnchorBottom, layout0, Qt::AnchorBottom, 1);
+
+ // layout0 to layout
+ layout->setAnchor(layout, Qt::AnchorLeft, layout0, Qt::AnchorLeft, 1);
+ layout->setAnchor(layout, Qt::AnchorTop, layout0, Qt::AnchorTop, 1);
+ layout->setAnchor(layout0, Qt::AnchorRight, layout, Qt::AnchorRight, 50);
+ layout->setAnchor(layout0, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
+
+ // widget1 to layout1
+ layout1->setAnchor(layout1, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
+ layout1->setAnchor(layout1, Qt::AnchorTop, widget1, Qt::AnchorTop, 1);
+ layout1->setAnchor(widget1, Qt::AnchorRight, layout1, Qt::AnchorRight, 1);
+ layout1->setAnchor(widget1, Qt::AnchorBottom, layout1, Qt::AnchorBottom, 1);
+
+ // layout1 to layout
+ layout->setAnchor(layout, Qt::AnchorLeft, layout1, Qt::AnchorLeft, 1);
+ layout->setAnchor(layout, Qt::AnchorTop, layout1, Qt::AnchorTop, 1);
+ layout->setAnchor(layout1, Qt::AnchorRight, layout, Qt::AnchorRight, 50);
+ layout->setAnchor(layout1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
+
+ TheAnchorLayout *layout2 = new TheAnchorLayout();
+
+ // layout2 to layout
+ layout->setAnchor(layout, Qt::AnchorLeft, layout2, Qt::AnchorLeft, 50);
+ layout->setAnchor(layout, Qt::AnchorTop, layout2, Qt::AnchorTop, 1);
+ layout->setAnchor(layout2, Qt::AnchorRight, layout, Qt::AnchorRight, 1);
+ layout->setAnchor(layout2, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
+
+ // transfer widget1 to layout2
+ layout2->setAnchor(layout2, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
+ layout2->setAnchor(layout2, Qt::AnchorTop, widget1, Qt::AnchorTop, 1);
+ layout2->setAnchor(widget1, Qt::AnchorRight, layout2, Qt::AnchorRight, 1);
+ layout2->setAnchor(widget1, Qt::AnchorBottom, layout2, Qt::AnchorBottom, 1);
+
+ widget->setGeometry(QRectF(0,0,100,100));
+ QCOMPARE(widget1->geometry(), QRectF(51,2,47,96));
+ delete widget;
+ }
+
+ // One widget, set first to one layout then to another. Child reparented.
+ // In addition widget as a direct child of another widget. Child reparented.
+ {
+ QGraphicsWidget *widget1 = new QGraphicsWidget;
+ TheAnchorLayout *layout1 = new TheAnchorLayout();
+ widget1->setLayout(layout1);
+
+ TestWidget *childWidget = new TestWidget();
+
+ // childWidget to layout1
+ layout1->setAnchor(layout1, Qt::AnchorLeft, childWidget, Qt::AnchorLeft, 1);
+ layout1->setAnchor(layout1, Qt::AnchorTop, childWidget, Qt::AnchorTop, 1);
+ layout1->setAnchor(childWidget, Qt::AnchorRight, layout1, Qt::AnchorRight, 1);
+ layout1->setAnchor(childWidget, Qt::AnchorBottom, layout1, Qt::AnchorBottom, 1);
+
+ widget1->setGeometry(QRectF(0,0,100,100));
+ QCOMPARE(childWidget->geometry(), QRectF(1,1,98,98));
+ QVERIFY(childWidget->parentLayoutItem() == layout1);
+ QGraphicsWidget *widget2 = new QGraphicsWidget;
+ TheAnchorLayout *layout2 = new TheAnchorLayout();
+ widget2->setLayout(layout2);
+
+ // childWidget to layout2
+ layout2->setAnchor(layout2, Qt::AnchorLeft, childWidget, Qt::AnchorLeft, 1);
+ layout2->setAnchor(layout2, Qt::AnchorTop, childWidget, Qt::AnchorTop, 1);
+ layout2->setAnchor(childWidget, Qt::AnchorRight, layout2, Qt::AnchorRight, 1);
+ layout2->setAnchor(childWidget, Qt::AnchorBottom, layout2, Qt::AnchorBottom, 1);
+
+ QGraphicsWidget *widget3 = new QGraphicsWidget;
+ QGraphicsWidget *widget4 = new QGraphicsWidget;
+ // widget4 is a direct child of widget3 (i.e. not in any layout)
+ widget4->setParentItem(widget3);
+
+ // widget4 to layout2
+ layout2->setAnchor(layout2, Qt::AnchorLeft, widget4, Qt::AnchorLeft, 1);
+ layout2->setAnchor(layout2, Qt::AnchorTop, widget4, Qt::AnchorTop, 1);
+ layout2->setAnchor(widget4, Qt::AnchorRight, layout2, Qt::AnchorRight, 1);
+ layout2->setAnchor(widget4, Qt::AnchorBottom, layout2, Qt::AnchorBottom, 1);
+
+ widget2->setGeometry(QRectF(0,0,100,100));
+ QCOMPARE(childWidget->geometry(), QRectF(1,1,98,98));
+ QVERIFY(childWidget->parentLayoutItem() == layout2);